From 6ef25563dda068239891364daacec88617d842bd Mon Sep 17 00:00:00 2001 From: Programmer001 <39063786+SimplyProgrammer@users.noreply.github.com> Date: Sun, 7 Aug 2022 14:02:35 +0200 Subject: [PATCH 01/75] Delete examples directory --- examples/Bar.java | 85 --------------- examples/Foo.java | 142 -------------------------- examples/GeneralExample.java | 114 --------------------- examples/Message.java | 35 ------- examples/ReadingJsonFromInternet.java | 31 ------ examples/SimpleCalculator.java | 66 ------------ examples/commentedExample.juss | 131 ------------------------ 7 files changed, 604 deletions(-) delete mode 100644 examples/Bar.java delete mode 100644 examples/Foo.java delete mode 100644 examples/GeneralExample.java delete mode 100644 examples/Message.java delete mode 100644 examples/ReadingJsonFromInternet.java delete mode 100644 examples/SimpleCalculator.java delete mode 100644 examples/commentedExample.juss diff --git a/examples/Bar.java b/examples/Bar.java deleted file mode 100644 index 2b05406..0000000 --- a/examples/Bar.java +++ /dev/null @@ -1,85 +0,0 @@ -package examples; - -import java.util.List; - -public final class Bar extends Foo //Sample object that inheres -{ - byte by0 = (byte) 142; - short s0 = 555; - double d2 = 5; - Object sampleParent; - - @Override - public String toString() - { - return "Bar[" + a + " " + b + " " + c + " " + d + " " + f + " " + ch + " " + s + " " + nah + " " + l + " " + by0 + " " + s0 + " " + sampleParent+"]"; - } - - public static class BarProtocol extends FooProtocol //Protocol to serialize Bar - { - @Override - public Object[] serialize(Foo object) - { - return new Object[] {object.a, object.b, object.c, object.d, object.f, object.ch, object.s, object.nah, object.l, ((Bar) object).by0, ((Bar) object).s0, "${$parent}" /*If serialized with JussSerializer this will try to get value of parent property from certain scope!*/}; - } - - @SuppressWarnings("unchecked") - @Override - public Foo unserialize(Class objectClass, Object... args) - { - Bar f = new Bar(); - f.a = (int) args[0]; - f.b = (int) args[1]; - f.c = (int) args[2]; - f.d = (double) args[3]; - f.f = (float) args[4]; - f.ch = (char) args[5]; - f.s = (String) args[6]; - f.nah = (boolean) args[7]; - f.l = (List) args[8]; - f.by0 = (byte) args[9]; - f.s0 = (short) args[10]; - f.sampleParent = args[11]; - - return f; - } - - @Override - public Class applicableFor() - { - return Bar.class; - } - } - - public byte getBy0() { - return by0; - } - - public void setBy0(byte by0) { - this.by0 = by0; - } - - public short getS0() { - return s0; - } - - public void setS0(short s0) { - this.s0 = s0; - } - - public double getD2() { - return d2; - } - - public void setD2(double d2) { - this.d2 = d2; - } - - public Object getSampleParent() { - return sampleParent; - } - - public void setSampleParent(Object sampleParent) { - this.sampleParent = sampleParent; - } -} diff --git a/examples/Foo.java b/examples/Foo.java deleted file mode 100644 index 51f1451..0000000 --- a/examples/Foo.java +++ /dev/null @@ -1,142 +0,0 @@ -package examples; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; -import java.util.concurrent.CopyOnWriteArrayList; - -import org.ugp.serialx.protocols.SerializationProtocol; - -public class Foo //Sample object to be serialized using its protocol! -{ - int a = 8, b = 1, c = 456; - double d = 5; - float f = 1453.364564564132454654511324f; - char ch = 'l'; - String s = "a"; - boolean nah = false; - List l = new CopyOnWriteArrayList(Arrays.asList(6, 45, 464654, 9.9, 56f)); - - public Foo() - { - l.add(6); - l.add(9); - l.add(13); - l.add(new Random()); - l.add(new ArrayList<>(Arrays.asList(4, 5, 6d, new ArrayList<>(), "hi"))); - } - - @Override - public String toString() - { - return "Foo[" + a + " " + b + " " + c + " " + d + " " + f + " " + ch + " " + s + " " + nah + " " + l + "]"; - } - - public static class FooProtocol extends SerializationProtocol //Protocol to serialize Foo - { - @Override - public Object[] serialize(Foo object) - { - return new Object[] {object.a, object.b, object.c, object.d, object.f, object.ch, object.s, object.nah, object.l}; - } - - @SuppressWarnings("unchecked") - @Override - public Foo unserialize(Class objectClass, Object... args) - { - Foo f = new Foo(); - f.a = (int) args[0]; - f.b = (int) args[1]; - f.c = (int) args[2]; - f.d = (double) args[3]; - f.f = (float) args[4]; - f.ch = (char) args[5]; - f.s = (String) args[6]; - f.nah = (boolean) args[7]; - f.l = (List) args[8]; - - return f; - } - - @Override - public Class applicableFor() - { - return Foo.class; - } - } - - public int getA() { - return a; - } - - public void setA(int a) { - this.a = a; - } - - public int getB() { - return b; - } - - public void setB(int b) { - this.b = b; - } - - public int getC() { - return c; - } - - public void setC(int c) { - this.c = c; - } - - public double getD() { - return d; - } - - public void setD(double d) { - this.d = d; - } - - public float getF() { - return f; - } - - public void setF(float f) { - this.f = f; - } - - public char getCh() { - return ch; - } - - public void setCh(char ch) { - this.ch = ch; - } - - public String getS() { - return s; - } - - public void setS(String s) { - this.s = s; - } - - public boolean isNah() { - return nah; - } - - public void setNah(boolean nah) { - this.nah = nah; - } - - public List getL() { - return l; - } - - public void setL(List l) { - this.l = l; - }; - - public static void a() {}; -} diff --git a/examples/GeneralExample.java b/examples/GeneralExample.java deleted file mode 100644 index d939136..0000000 --- a/examples/GeneralExample.java +++ /dev/null @@ -1,114 +0,0 @@ -package examples; - -import java.io.File; -import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicLong; - -import org.ugp.serialx.JussSerializer; -import org.ugp.serialx.Scope; -import org.ugp.serialx.protocols.SerializationProtocol; - -/** - * This example is overview of general SerialX API functionalities! - * We will look at how to serialize and deserialize objects using file. We will also create protocols for our objects as well as for already existing ones! - * This example is also for benchmarking! - * - * @author PETO - * - * @since 1.0.0 - */ -public class GeneralExample -{ - public static void main(String[] args) throws Exception - { - //Protocol registration - SerializationProtocol.REGISTRY.addAll(new Bar.BarProtocol(), new Foo.FooProtocol(), new SerializationProtocol() //Sample custom protocol to serialized Random. - { //Random will be serialized also without protocol via classic Java Base64 because it implements java.io.Serializable! - @Override - public Object[] serialize(Random object) - { - try - { - Field f = Random.class.getDeclaredField("seed"); - f.setAccessible(true); - return new Object[] {((AtomicLong) f.get(object)).get()}; - } - catch (Exception e) - { - e.printStackTrace(); - return new Object[] {-1}; - } - } - - @Override - public Random unserialize(Class objectClass, Object... args) - { - return new Random(((Number) args[0]).longValue()); - } - - @Override - public Class applicableFor() - { - return Random.class; - } - }); - - File f = new File("test.juss"); //File to write and read from! - - //Sample objects - Random r = new Random(); - List list = new ArrayList<>(); - for (int i = 0; i < 8; i++) - list.add(r.nextBoolean() ? r.nextInt(i+1) : r.nextBoolean()); - - HashMap vars = new HashMap<>(); //Variables to serialize - vars.put("yourMom", "is heavier than sun..."); - vars.put("num", 6); - - int[][] ints = {{1, 2, 3}, {4, 5, 4}, {3, 2, 1}}; - - //-------------------------------------------Serializing------------------------------------------- - - JussSerializer serializer = new JussSerializer(vars); //Creating an instance of Serializer that will serialize objects using Juss! Serializer is instance of scope so it behaves like so! - //Adding independent values Invokation of static members of this class (calling method "println" and obtaining "hello" field as argument! - serializer.addAll("some string", r, list, serializer.Comment("Size of array"), serializer.Var("arrSize", list.size()), new Bar(), 1, 2.2, 3, 'A', true, false, null, ints, serializer.Code("$num"), new Scope(), serializer.StaticMember(GeneralExample.class, "println", serializer.StaticMember(GeneralExample.class, "hello"))); - //This will insert an comment Another way to add variable except Map $ is used to obtain value from variable - serializer.setGenerateComments(true); //Enabling comment generation - - double t0 = System.nanoTime(); - serializer.SerializeTo(f); //Saving content of serializer to file (serializing) - double t = System.nanoTime(); - System.out.println("Write: " + (t-t0)/1000000 + " ms"); //Write benchmark - - //-------------------------------------------Deserializing------------------------------------------- - - SerializationProtocol.REGISTRY.setActivityForAll(true); //Enabling all protocols, just in case... - - JussSerializer deserializer = new JussSerializer(); //Creating instance of Serializer that will deserialize objects serialized in Juss (same class is responsible for serializing and deserializing)! - deserializer.setParsers(JussSerializer.JUSS_PARSERS_AND_OPERATORS); - deserializer.put("parent", "father"); //Setting global variables - - t0 = System.nanoTime(); - deserializer.LoadFrom(f); //Loading content of file in to deserializer! - t = System.nanoTime(); - System.out.println("Read: " + (t-t0)/1000000 + " ms"); //Read benchmark - - //deserializer = (JussSerializer) deserializer.filter(obj -> obj != null); //This will filter away every null value and variable! - - //Printing values and variables of scope! - System.out.println(deserializer.variables()); - System.out.println(deserializer.values()); - } - - //We can invoke static members in JUSS! - public static String hello = "Hello world!"; - - public static void println(String str) - { - System.out.println(str); - } -} diff --git a/examples/Message.java b/examples/Message.java deleted file mode 100644 index ed534da..0000000 --- a/examples/Message.java +++ /dev/null @@ -1,35 +0,0 @@ -package examples; - -import org.ugp.serialx.protocols.SelfSerializable; - -/** - * Example of self-serializable object! - * - * @author PETO - * - * @see SelfSerializable - * - * @since 1.3.2 - */ -public class Message implements SelfSerializable -{ - public String str; - public int date; - - public Message(String str, int date) - { - this.str = str; - this.date = date; - } - - @Override - public String toString() { - return "Message["+str+", "+date+"]"; - } - - @Override - public Object[] serialize() - { - return new Object[] {str, date}; - } -} diff --git a/examples/ReadingJsonFromInternet.java b/examples/ReadingJsonFromInternet.java deleted file mode 100644 index bb36f97..0000000 --- a/examples/ReadingJsonFromInternet.java +++ /dev/null @@ -1,31 +0,0 @@ -package examples; - -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; - -import org.ugp.serialx.JsonSerializer; - -/** - * In this example we can see how to perform json reading from remote web url! - * Note: Internet connection is required for this example to work! - * - * @author PETO - * - * @since 1.3.2 - */ -public class ReadingJsonFromInternet -{ - public static void main(String[] args) throws IOException - { - //Creating JsonSerializer that can parse json! - JsonSerializer reader = new JsonSerializer(); - - InputStream urlInput = new URL("https://jsonplaceholder.typicode.com/users").openStream(); //Establishing connection with https://jsonplaceholder.typicode.com/users and getting stream of received data! - reader.LoadFrom(urlInput); //Parsing url stream content into json! - - String user = "Glenna Reichert"; //User we want to get (Glenna Reichert)! - String glennasCompany = reader.getScopesWith("name", user).get(0).getScope("company").getString("name"); //Obtaining first scope that contains variable with users name and getting name of his company as string from it! - System.out.println(user + " is working for " + glennasCompany); //Printing results! - } -} diff --git a/examples/SimpleCalculator.java b/examples/SimpleCalculator.java deleted file mode 100644 index e29cd7a..0000000 --- a/examples/SimpleCalculator.java +++ /dev/null @@ -1,66 +0,0 @@ -package examples; - -import java.util.Scanner; - -import org.ugp.serialx.Registry; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.NumberConverter; -import org.ugp.serialx.converters.OperationGroups; -import org.ugp.serialx.converters.operators.ArithmeticOperators; - -/** - * This example will show you simple implementation of SerialX latest feature the recursive data parser! - * In this example we will be creating simple evaluator of mathematical expressions! - * - * @author PETO - * - * @since 1.3.0 - */ -public class SimpleCalculator -{ - static Scanner scIn = new Scanner(System.in); - - public static void main(String[] args) - { - /* - * We could easily just use DataParser.REGISTRY but there is tone of stuff we do not need and it will just slow it down! - */ - Registry parsersRequiredToEvaluateMath = new Registry<>(new OperationGroups(), new ArithmeticOperators(), new NumberConverter()); - - /* - * This is an example of simple custom parser this one will allow us to reuse answers of out previous evaluations! - * We will access this old answer using 'ans' word! - * Old ans must be provided as first one of args! - */ - DataParser ansParser = new DataParser() - { - @Override - public Object parse(Registry myHomeRegistry, String str, Object... args) - { - if (str.equalsIgnoreCase("ans")) - { - if (args.length > 0) - return args[0]; //First arg is old answer! - return null; - } - return CONTINUE; - } - }; - parsersRequiredToEvaluateMath.add(ansParser); - - Object oldAns = null; - while (true) - { - System.out.print("Please insert your math problem: "); //Ask for input! - String input = scIn.nextLine() ;//Read console input - if (!(input = input.trim()).isEmpty()) //Avoiding empty input! - { - double t0 = System.nanoTime(); //Performing simple benchmark - oldAns = DataParser.parseObj(parsersRequiredToEvaluateMath, input, oldAns); //Notice that we are inserting oldAns as compiler arguments for parseObj which are then picked up by our ansParser as well as every other registered DataParser. - double t = System.nanoTime(); - - System.out.println(input + " = " + oldAns +"\n" + (t-t0)/1000000 + "ms \n"); //Parsing input! - } - } - } -} diff --git a/examples/commentedExample.juss b/examples/commentedExample.juss deleted file mode 100644 index ed6085c..0000000 --- a/examples/commentedExample.juss +++ /dev/null @@ -1,131 +0,0 @@ -/* THIS IS HOW RESULT OF SERIALX (Juss) REAL LIFE IMPLEMENTATION MIGHT LOOK LIKE */ - -name = "app"; - -dependencies = -{ - //This is scope, the Juss representation of ugp.org.SerialX.Scope! - //Each scope can have its own variables with values and independant values! - - //Every scope can read and write parent scopes variables however by changing them, it will only affect local one and not parents one! - $name; //"app" ($ obtains value from variable, in this case "app") - $name = "no longer app lol!"; - - composition-api = "1.0.0 (beta)", //This is one of the variables of this scope... - bootstrap = "4.5.3", - version = "2.3.4", - something = - { - dataStorage = - { - //This is "dataStorage" (stored by variable "dataStorage") sub-scope aka nested skope of its parent scope "something" which is subscope of "dependencies", - xml = - { - version = "2.8.0" - }, - yaml = - { - version = "1.10.5" - }, - josn = - { - version = "4.0.0" - }, - serialx = - { - version = "The best version!" - } - }, - ppl = - { - //This is "ppl" (stored by variable "ppl") sub-scope aka nested skope of its parent scope "something" which is subscope of "dependencies". - //All of these scopes are sub-scopes of "ppl", there can be infinite number of variables and independent values together in one Scope! - vladimir = - { - age = 37; - residence = "russia"; - }, - ivan = - { - age = 19; - residence = "russia"; - }, - filip = - { - age = 17; - residence = "slovak"; - }, - peter = - { - age = 17; - residence = "slovak"; - }, - lukas = - { - age = 17; - residence = "slovak"; - }, - hans = - { - age = 51; - residence = "germany"; - }, - pierre = - { - age = 44; - residence = "france"; - } - } - }, - "lololoolollool"; //This is independent value of this scope. -}, -$dependencies.something.dataStorage.serialx.version; //Obtaining value of "serialx" variable in "dependencies" sub-scopes! - -devDependencies = -{ - //Variables in this scope have nothing to do with variables from "dependencies" because they are in diffrent scope! - $name = "absolutely not app!"; - - composition-api = "1.0.0 (alpha)", - bootstrap = "2.2.3", - version = "1.2.3", - something = - { - dataStorage = {}, - ppl = {} - } -}; -//Setting variable of scope from outer world (possible since 1.3.2) -devDependencies.something.ppl.ludvig = -{ - age = 60; - residence = "russia"; -}; - -//Since 1.2.5 Serializer fully supports Json and JavaScript object! -jsonCrossover = -{ - "hello" : "Hello world I am Javascript object notation!", - "jsonObject" : - { - name: "John", - age: 31, - city: "New York" - }, - "jsonArray" : [1, 2, 3, 4] -}, - -//$bullshit <-- No this is not possible, variable "bullshit" cannot be accessed here because it was not initialized yet! -bullshit = -{ - //This scope cant access variable that is stored by (bullshit), because variable is always created after its value (Scope in this case) is constructed! - server = "service server", - build = "service build", - sql = "service sql"; -}, -$bullshit; //Now we can access variable "bullshit" - -$name; //"name" is still "app" in this scope! - -arr = {1, 2, 3, 4, 5}; //This is scope with only values! So lets call it... array I guess! -superArr = {$arr, $arr, $arr, $arr::new /*creates clone of arr*/, {1, 2, 3, 4, 5}}; //Yes... this is completely normal and possible in Juss but keep in mind that first, second and third element will refere to same instance in this case! From 4714f4344a9d856a315d505c483ba82a2b285dad Mon Sep 17 00:00:00 2001 From: Programmer001 <39063786+SimplyProgrammer@users.noreply.github.com> Date: Sun, 7 Aug 2022 14:11:38 +0200 Subject: [PATCH 02/75] Update README.md --- README.md | 136 +----------------------------------------------------- 1 file changed, 2 insertions(+), 134 deletions(-) diff --git a/README.md b/README.md index f0b7292..8f0b6c0 100644 --- a/README.md +++ b/README.md @@ -1,134 +1,2 @@ -# Java-SerialX -SerialX is a powerful utility library to serialize objects in Java. Serialization means storing Java objects and values into file.
-SerialX is improving regular Java Base64 serialization and adding serialization protocols that you can create for objects that cant be serialized using regular way. For example final non-serializable objects, 3rd party objects and others. SerialX API is storing objects into JSON like "programming" language (data format) called JUSS (Java universal serial script) which shares common functionality with JSON and provides more customizability and extended functionality! This allows you to serialize multiple objects into one string or also into file. But unlike to JSON, JUSS general conception is based on determinate order of arguments or values we can say. Latest versions also provides variable system (keys, values) similar to JSON. But in JUSS these variables can be overided and can interact with each other and can be used multiple times. Nowadays SerialX provides recursive descent parser that can be modified so you can create your own data structures! In other words SerialX allows you to serialize **anything**, it's pretty simple to use and practically limitless! -## Brief overview of working concept and advantages compared to regular serialization: -**Regular java serialization** is strongly based on some kind of "magic" or we can say "godly reflection" which will reflectivly read all fields of object includeing private and final ones and then interprets it as Base64 string. And during deserialization it will create an empty instance of object absolutly ignoring its constructors by using some "magic" compilator process to create it instad, and then it will violently write all serialized field again includeing private and final ones which is realy not the best aproach! Also this alows you to serialize only instances of java.io.Serializable and all field must be instances of Serializable as well which is also not the most usefull thing!
-Compare to this, **SerialX API** is doing everything programmatically. SerialX API uses ``SerializationProtocol``s that are registred in ``ProtocolRegistry``, each working for certain class! ``SerializationProtocol`` contains 2 methods, ``serialize(T object)`` and ``unserialize(Object[] args)``. ``serialize(T object)`` method obtains certain object to serialize and its job is to turn this object into array of objects that we can then reconstruct this exact object from, such as constructor arguments! These arguments are then paste into ``Serializer`` and ``Serializer`` serialize them into mentioned SerialX API data storage format. During deserialization, ``Serializer`` first takes givven data serialized in SerialX, unserialize them into array of objects and this array is then paste into ``unserialize(Object[] args)`` method of certain ``SerializationProtocol`` as argument. Job of ``unserialize(Object[] args)`` method is to create an new instance of serialized object ``T`` from givven arguments! Evrything in this function is controlled by you and you can write them by your self which gives you an absolute control!
-Note: Since 1.3.0, protocols are operated by DataParsers and are mainly used for more complex objects. Also Object to String conversion is now done by DataConverter and String - Object is done by DataParsers and further by protocols! -**Advantages and goals:** -* Overcoming most of regular serialization problems such as bypassing constructor! -* Powerful and highly costomizable/opinionated, you have control over stuff via protocols and recursive descent parser! -* Programmaticall, meaning you can decide how objects will be serialized and deserialized! -* Fast, SerialX solution is almost always far more faster than regular serialization! -* Readable, It depends but SerialX formats are supposed to be pretty readable for humans and should be also pretty intuitive for learning and writing! -* Data types recognision, SerialX defaultly supports all primitve datatypes from java and also objects (done with protocols) compare to Json for instance! -* Small storage requirements, as you can see belove SerialX is often times far smaller than Json not even mentioning XML! -* Quantity, SerialX can serialize multiple objects into one file or string! -* Fully compatible with JSON! -* Very easy to use, at the begining all what you need to know is ``Serializer.SerializeTo(file, objects)`` for serializing and ``Serializer.LoadFrom(file)`` for deserializing! -* Recursive descent parser that is fully customizable and can be used to parse and convert potentialy anything from JSON to CSS! - -## Comparison: XML (.xml) vs Json (.json) vs YAML (.yml) vs JUSS (.juss or .srlx) -Sample object: -``` -public class Foo -{ - double val1 = 55, val2 = 455.45; - float val3 = 236.12F; - boolean flag = true; - - public double getVal1() - { - return val1; - } - public void setVal1(double val1) - { - this.val1 = val1; - } - public double getVal2() - { - return val2; - } - public void setVal2(double val2) - { - this.val2 = val2; - } - public float getVal3() - { - return val3; - } - public void setVal3(float val3) - { - this.val3 = val3; - } - public boolean isFlag() - { - return flag; - } - public void setFlag(boolean flag) - { - this.flag = flag; - } -} -``` -## -Serialized via **XMLDecoder for XML:** -``` - - - - - 55 - - - 455.45 - - - 236.12 - - - true - - - -``` -
Serialized via **JACKSONE (hypothetical) for Json:** -``` -... -{ - "val1" : 55.0, - "val2" : 455.45, - "val3" : 236.12, - "flag" : true -} -``` -
Serialized via **(hypothetical) YAML:** -``` -val1: 55.0 -val2: 455.45 -val3: 236.12 -flag: true -``` -
Serialized via **SerialX for JUSS (protocol):** -``` -some.package.Foo 55D 455.45 236.12F T; -``` -## After introduction of variables in 1.1.5 and scope in 1.2.0:
-Serialized via **SerialX for JUSS (protocol + scope):** -``` -some.package.Foo { - val1 = 55D, - val2 = 455.45, - val3 = 236.12F, - flag = T -} -``` -
Serialized via **SerialX for JUSS (scope only):** -``` -{ - val1 = 55D, - val2 = 455.45, - val3 = 236.12F, - flag = T -} -``` -
Maybe it is a question of formating but JUSS with protocol will be the shortest one anyway. Because, in this case, instead of having some sort of key to the value you simply have its order (index)! -And value's data type is specified by suffix if it is a primitive data type or simply by package name as the first argument in case of an object! Other arguments (count, order, type) are then specified by a SerializationProtocol! Generally, one line means one object, one value (separated by spaces) means one argument!

-Note: Since there is variable system in 1.1.5, the order of values is now not the only option to obtain an object or value!
-
-## Info -* If you want to add or see issues just click on [Issues section](https://github.com/PetoPetko/Java-SerialX/issues) in up. -* If you want to comment or suggest an feature use [Discussions section](https://github.com/PetoPetko/Java-SerialX/discussions). -* If you want to see or learn some things about library then see the documentation or Sample Open Source Implementation. -* If you want to download library, dont use commits section, use [Releases section](https://github.com/PetoPetko/Java-SerialX/releases) or click that big green button "Clone or download" to download the latest version. -* And if you want to see changelog open [changelog file](Changelog.md) or use [Releases section](https://github.com/PetoPetko/Java-SerialX/releases) too. +# Java-SerialX dev +This branch is used for testing and stuff! From eded64bd6f7caec39a93674d2ce2eef008f80055 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 19 Jun 2023 14:37:43 +0200 Subject: [PATCH 03/75] gegining of modularisation --- .gitignore | 37 + .project | 17 + .settings/org.eclipse.m2e.core.prefs | 4 + SerialX-core/.classpath | 38 + SerialX-core/.project | 23 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../.settings/org.eclipse.m2e.core.prefs | 4 + SerialX-core/pom.xml | 13 + .../java/org/ugp/serialx/GenericScope.java | 911 ++++++++ .../java/org/ugp/serialx/JussSerializer.java | 864 ++++++++ .../java/org/ugp/serialx/LogProvider.java | 63 + .../main/java/org/ugp/serialx/Registry.java | 404 ++++ .../src/main/java/org/ugp/serialx/Scope.java | 1285 +++++++++++ .../ugp/serialx/SerializationDebugger.java | 400 ++++ .../main/java/org/ugp/serialx/Serializer.java | 1880 +++++++++++++++++ .../serialx/converters/ArrayConverter.java | 199 ++ .../serialx/converters/BooleanConverter.java | 89 + .../converters/CharacterConverter.java | 69 + .../ugp/serialx/converters/DataConverter.java | 103 + .../ugp/serialx/converters/DataParser.java | 427 ++++ .../ugp/serialx/converters/NullConverter.java | 61 + .../serialx/converters/NumberConverter.java | 205 ++ .../serialx/converters/ObjectConverter.java | 525 +++++ .../serialx/converters/OperationGroups.java | 185 ++ .../SerializableBase64Converter.java | 150 ++ .../serialx/converters/StringConverter.java | 101 + .../serialx/converters/VariableConverter.java | 222 ++ .../serialx/converters/imports/Import.java | 129 ++ .../converters/imports/ImportConverter.java | 267 +++ .../converters/imports/ImportsProvider.java | 130 ++ .../operators/ArithmeticOperators.java | 495 +++++ .../operators/ComparisonOperators.java | 184 ++ .../ConditionalAssignmentOperators.java | 123 ++ .../operators/LogicalOperators.java | 152 ++ .../operators/NegationOperator.java | 81 + .../ugp/serialx/protocols/AutoProtocol.java | 235 +++ .../ugp/serialx/protocols/EnumProtocol.java | 33 + .../ugp/serialx/protocols/ListProtocol.java | 44 + .../ugp/serialx/protocols/MapProtocol.java | 50 + .../ugp/serialx/protocols/ScopeProtocol.java | 47 + .../serialx/protocols/SelfSerializable.java | 22 + .../protocols/SelfSerializableProtocol.java | 31 + .../protocols/SerializationProtocol.java | 450 ++++ .../ugp/serialx/protocols/StringProtocol.java | 62 + .../UniversalObjectInstantiationProtocol.java | 61 + SerialX-json/.classpath | 38 + SerialX-json/.project | 23 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../.settings/org.eclipse.m2e.core.prefs | 4 + SerialX-json/pom.xml | 21 + .../org/ugp/serialx/json/JsonSerializer.java | 403 ++++ .../converters/JsonCharacterConverter.java | 28 + .../json/converters/JsonNumberConverter.java | 14 + .../json/converters/JsonObjectConverter.java | 48 + pom.xml | 58 + 55 files changed, 11528 insertions(+) create mode 100644 .gitignore create mode 100644 .project create mode 100644 .settings/org.eclipse.m2e.core.prefs create mode 100644 SerialX-core/.classpath create mode 100644 SerialX-core/.project create mode 100644 SerialX-core/.settings/org.eclipse.jdt.core.prefs create mode 100644 SerialX-core/.settings/org.eclipse.m2e.core.prefs create mode 100644 SerialX-core/pom.xml create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/Registry.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/Scope.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/Serializer.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java create mode 100644 SerialX-json/.classpath create mode 100644 SerialX-json/.project create mode 100644 SerialX-json/.settings/org.eclipse.jdt.core.prefs create mode 100644 SerialX-json/.settings/org.eclipse.m2e.core.prefs create mode 100644 SerialX-json/pom.xml create mode 100644 SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java create mode 100644 SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java create mode 100644 SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java create mode 100644 SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..04f470d --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +# Specifies intentionally untracked files to ignore when using Git +# http://git-scm.com/docs/gitignore + +*~ +*.sw[mnpcod] +.tmp +*.tmp +*.tmp.* +*.sublime-project +*.sublime-workspace +.DS_Store +Thumbs.db +UserInterfaceState.xcuserstate +$RECYCLE.BIN/ + +*.log +log.txt +npm-debug.log* + +/.idea +/.ionic +/.sass-cache +/.sourcemaps +/.versions +/.vscode +/coverage +/dist +/node_modules +/platforms +/plugins +/www + +bin/ +tmp/ +.metadata + +target/ diff --git a/.project b/.project new file mode 100644 index 0000000..bbfcc34 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + SerialXDev + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SerialX-core/.classpath b/SerialX-core/.classpath new file mode 100644 index 0000000..002ad57 --- /dev/null +++ b/SerialX-core/.classpath @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/.project b/SerialX-core/.project new file mode 100644 index 0000000..75fcc6c --- /dev/null +++ b/SerialX-core/.project @@ -0,0 +1,23 @@ + + + SerialX-core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SerialX-core/.settings/org.eclipse.jdt.core.prefs b/SerialX-core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..2f5cc74 --- /dev/null +++ b/SerialX-core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-core/.settings/org.eclipse.m2e.core.prefs b/SerialX-core/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/SerialX-core/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml new file mode 100644 index 0000000..d26d70a --- /dev/null +++ b/SerialX-core/pom.xml @@ -0,0 +1,13 @@ + + 4.0.0 + + org.ugp + serialx + 1.3.7 + + org.ugp.serialx + core + + SerialX-core + Core of SerialX + \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java new file mode 100644 index 0000000..0cd2c1f --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -0,0 +1,911 @@ +package org.ugp.serialx; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.ugp.serialx.converters.ArrayConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + + +/** + * This is some kind of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
+ * Note: Variables are managed and accessed classically via {@link Map} methods such as put(KeyT key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
+ * Also this is java representation of JUSS GenericScope group such as: + *
+ * 
+ * {
+ *     //This is generic scope in JUSS! Variable keys are generic!
+ * }
+ * 
+ * 
+ * + * @author PETO + * + * @since 1.2.0 + * + * @param generic type of variables key. + * @param generic type of variables value and independent value. + */ +public class GenericScope implements Iterable, Cloneable, Serializable +{ + private static final long serialVersionUID = 5717775602991055386L; + + protected Map variables; + protected List values; + protected GenericScope parent; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + @SafeVarargs + public GenericScope(ValT... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + @SafeVarargs + public GenericScope(Map variablesMap, ValT... values) + { + this(variablesMap, values == null ? null : Arrays.asList(values), null); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + public GenericScope(Map variablesMap, Collection values) + { + this(variablesMap, values, null); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + + * @since 1.2.0 + */ + public GenericScope(Map variablesMap, Collection values, GenericScope parent) + { + if (variablesMap != null) + this.variables = new LinkedHashMap<>(variablesMap); + if (values != null) + this.values = new ArrayList<>(values); + this.parent = parent; + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof GenericScope) + return values().equals(((GenericScope) obj).values()) && variables().equals(((GenericScope) obj).variables()); + else if (obj instanceof Collection) + return variablesCount() <= 0 && values().equals(obj); + else if (obj instanceof Map) + return valuesCount() <= 0 && variables().equals(obj); + else if (obj != null && obj.getClass().isArray()) + return variablesCount() <= 0 && Objects.deepEquals(toValArray(), ArrayConverter.fromAmbiguous(obj)); + return super.equals(obj); + } + + @Override + public String toString() + { + String name = getClass().getSimpleName(); + if (variablesCount() > 0 ^ valuesCount() > 0) + return name + (variablesCount() > 0 ? variables() : values()); + else + return name + toUnifiedList(); + } + + @SuppressWarnings("unchecked") + @Override + public GenericScope clone() + { + try + { + return clone(getClass()); + } + catch (Exception e) + { + return new GenericScope<>(variables(), values(), getParent()); + } + } + + /** + * @param typeOfClone | Class representing type of scope that will be created. + * @return Copy of this scope converted to instance of typeOfClone. + * + * @throws Exception | When program was unable to create instance of typeOfClone. + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public > S clone(Class typeOfClone) throws Exception + { + S clone = Serializer.Instantiate(typeOfClone); + clone.values = (List) toValList(); + clone.variables = (Map) toVarMap(); + clone.parent = getParent(); + return (S) clone; + } + + /** + * @param newType | Type of new scope. + * @return Original scope retyped/casted into instance of newType. Similar to {@link GenericScope#clone(Class)} but this will share same instances of values list and variables map with original! + * + * @throws Exception | When program was unable to create instance of newType. + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public > S castTo(Class newType) throws Exception + { + if (getClass() == newType) + return (S) this; + + GenericScope clone = (GenericScope) Serializer.Instantiate(newType); + clone.values = (List) values(); + clone.variables = (Map) variables(); + clone.parent = getParent(); + return (S) clone; + } + + /** + * @return Iterator of independent values. + * + * @since 1.2.0 + */ + @Override + public Iterator iterator() + { + return values().iterator(); + } + + /** + * Insert new variable. + * + * @param variableKey | Name of variable. + * @param variableValue | Variables value. + * + * @return Old value of variable with given name or null is there was no this variable before! + * + * @since 1.2.0 + */ + public ValT put(KeyT variableKey, ValT variableValue) + { + if (variableValue instanceof GenericScope && ((GenericScope) variableValue).getParent() == null) + ((GenericScope) variableValue).parent = this; + return variables().put(variableKey, variableValue); + } + + /** + * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... + * + * @return Array of values previously at keys from kv array. + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public ValT[] putAllKv(Object... kVkVkV) + { + ValT[] oldValues = (ValT[]) new Object[kVkVkV.length/2]; + for (int i = 1; i < kVkVkV.length; i+=2) { + oldValues[i/2] = put((KeyT) kVkVkV[i-1], (ValT) kVkVkV[i]); + } + return oldValues; + } + + /** + * @param index | Index of variable! + * + * @return Value of variable at required index or null if index was not found! + * + * @since 1.2.5 + */ + public V getVarAt(int index) + { + return getVarAt(index, null); + } + + /** + * @param index | Index of variable! + * @param defaultValue | Default value to return. + * + * @return Value of variable at required index or defaultValue if index was not found! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public V getVarAt(int index, V defaultValue) + { + int i = 0; + for (Map.Entry ent : varEntrySet()) + if (i++ == index) + return (V) ent.getValue(); + return defaultValue; + } + + /** + * @param variableKey | Variables name. + * + * @return Value of variable with name or null if there is no such a one! + * + * @since 1.2.0 + */ + public V get(KeyT variableKey) + { + return get(variableKey, null); + } + + /** + * @param variableKey | Variables name. + * @param defaultValue | Default value to return. + * + * @return Value of variable with name or defaultValue if there is no such a one! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public V get(KeyT variableKey, V defaultValue) + { + V obj = (V) variables().get(variableKey); + if (obj == null) + return (V) defaultValue; + return obj instanceof Serializer.NULL ? null : obj; + } + + /** + * @param variableKey | Variables name to search for. + * + * @return True if variable with given name was found in this scope. + * + * @since 1.2.0 + */ + public boolean containsVariable(KeyT variableKey) + { + for (Map.Entry ent : varEntrySet()) + if (ent.getKey().equals(variableKey)) + return true; + return false; + } + + /** + * @param value | Objecthe value. + * + * @return True if independent value was found in this scope. + * + * @since 1.2.0 + */ + public boolean containsIndependentValue(ValT value) + { + return values().contains(value); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent value with valueIndex. + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public V get(int valueIndex) + { + V obj = (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); + return obj instanceof Serializer.NULL ? null : obj; + } + + /** + * @param value | Independent value to add into array of values. + * + * @return {@link ArrayList#add(Object)} + * + * @since 1.2.0 + */ + public boolean add(ValT value) + { + boolean result = values().add(value); + if (result && value instanceof GenericScope && ((GenericScope) value).getParent() == null) + ((GenericScope) value).parent = this; + return result; + } + + /** + * @param values | List of independent value or values to add into array of values. + * + * @return {@link ArrayList#add(Object)} + * + * @since 1.2.0 + */ + public boolean addAll(Collection values) + { + if (values.isEmpty()) + return false; + return values().addAll(values); + } + + /** + * @param values | Array of independent value or values to add into array of values. + * + * @return {@link GenericScope#addAll(Object...)} + * + * @since 1.3.2 + */ + public boolean addAll(@SuppressWarnings("unchecked") ValT... values) + { + return addAll(Arrays.asList(values)); + } + + /** + * @param scopeValueIndex | Index of sub-scopes value. + * + * @return Sub-scope on required index or null if there is no scope on required index!
+ * Note: Keep in mind that you need to insert valid index according to other values. Scopes share same index order with other values! + * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public GenericScope getGenericScope(int scopeValueIndex) + { + GenericScope obj = (GenericScope) get(scopeValueIndex); + if (obj instanceof GenericScope) + return (GenericScope) obj; + return null; + } + + /** + * @param scopesPath | Array with variables creating path to required scope. + * + * @return Sub-scope stored by variable with required name (last element) in inserted path or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! + * This search will also includes sub-scopes of scope but variables from lower ones are prioritize!
+ * If this function is called with no arguments then self will be returned! + * Note: Remember that this search includes variables only, no values!
+ * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public GenericScope getGenericScope(K... scopesPath) + { + try + { + if (scopesPath.length <= 0) + return (GenericScope) this; + Object obj = get((KeyT) scopesPath[0]); + if (obj instanceof GenericScope) + return ((GenericScope) obj).getGenericScope(scopesPath = Arrays.copyOfRange(scopesPath, 1, scopesPath.length)); + for (Map.Entry var : varEntrySet()) + if (var.getValue() instanceof GenericScope) + try + { + GenericScope sc = (GenericScope) var.getValue(); + if ((sc = sc.getGenericScope(scopesPath[0])) != null) + return sc.getGenericScope(scopesPath = Arrays.copyOfRange(scopesPath, 1, scopesPath.length)); + } + catch (Exception e) {} + + if (containsVariable((KeyT) scopesPath[0])) + LogProvider.instance.logErr("Variable with name \"" + scopesPath[0] + "\" does exists! However its value is not instance of scope, use \"get\" function instead if possible!", null); + } + catch (ClassCastException e) + {} + return null; + } + + /** + * @param objClass | Object of class to create. + * + * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + public T toObject(Class objClass) throws Exception + { + return toObject(objClass, SerializationProtocol.REGISTRY); + } + + /** + * @param objClass | Object of class to create using protocols. + * @param protocolsToUse | Registry of protocols to use. + * + * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.3.2 + */ + public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception + { + SerializationProtocol pro = protocolsToUse == null ? null : protocolsToUse.GetProtocolFor(objClass, SerializationProtocol.MODE_DESERIALIZE); + if (pro != null) + { + T obj = pro.unserialize(objClass, this.variablesCount() > 0 ? new Object[] {this} : this.toValArray()); + if (obj != null) + return obj; + } + return null; + } + + /** + * @param predicate | Predicate object with filter condition in test method! + * + * @return Original scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * + * @since 1.2.5 + */ + public GenericScope filter(Predicate predicate) + { + return filter(predicate, false); + } + + /** + * @param predicate | Predicate object with filter condition in test method! + * @param includeSubScopes | If true filtration will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Predicate#test(Object)}). + * If sub-scope is empty after filtration it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Original scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public GenericScope filter(Predicate predicate, boolean includeSubScopes) + { + return (GenericScope) transform(new Function() + { + @Override + public Object apply(ValT t) + { + return predicate.test(t) ? t : DataParser.VOID; + } + }, includeSubScopes); + } + + /** + * @param trans | Function to transform objects of this scope! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * + * @since 1.2.5 + */ + public GenericScope transform(Function trans) + { + return transform(trans, false); + } + + /** + * @param trans | Function to transform objects of this scope! + * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). + * If sub-scope is empty after transformation it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public GenericScope transform(Function trans, boolean includeSubScopes) + { + if (trans == null || isEmpty()) + return (GenericScope) this; + + List fltVals = map(trans, includeSubScopes); + LinkedHashMap fltVars = new LinkedHashMap<>(); + + for (Entry ent : this.varEntrySet()) + try + { + Object obj = ent.getValue(); + obj = obj instanceof Serializer.NULL ? null : obj; + if (obj instanceof GenericScope && includeSubScopes) + { + GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); + if (!sc.isEmpty()) + fltVars.put(ent.getKey(), (V) sc); + } + else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) + fltVars.put(ent.getKey(), trans.apply((ValT) obj)); + } + catch (ClassCastException e) + {} + + try + { + GenericScope clone = Serializer.Instantiate(getClass()); + clone.values = fltVals; + clone.variables = fltVars; + clone.parent = getParent(); + return clone; + } + catch (Exception e) + { + return new GenericScope<>(fltVars, fltVals, getParent()); + } + } + + /** + * @param trans | Function to transform objects of this scope! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.3.5 + */ + public List map(Function trans) + { + return map(trans, false); + } + + /** + * @param trans | Function to transform objects of this scope! + * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). + * If sub-scope is empty after transformation it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public List map(Function trans, boolean includeSubScopes) + { + List fltVals = new ArrayList<>(); + for (Object obj : this) + try + { + obj = obj instanceof Serializer.NULL ? null : obj; + if (obj instanceof GenericScope && includeSubScopes) + { + GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); + if (!sc.isEmpty()) + fltVals.add((V) sc); + } + else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) + fltVals.add((V) obj); + } + catch (ClassCastException e) + {} + + return fltVals; + } + + /** + * @param valueIndex | Index of independent value to remove! + * + * @return Removed independent value! + * + * @since 1.3.2 + */ + public ValT remove(int valueIndex) + { + return values().remove(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); + } + + /** + * @param variableKey | Name of variable to remove! + * + * @return Value of variable that was removed! + * + * @since 1.3.2 + */ + public ValT remove(KeyT variableKey) + { + return variables().remove(variableKey); + } + + /** + * Removes all independent values and variables of this scope! + *
+ * Basically it just calls variables().clear() and values().clear()! + * + * @since 1.3.5 + */ + public void clear() + { + variables().clear(); + values().clear(); + } + + /** + * @return This scope after inheriting variables of its parent (return this)! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public GenericScope inheritParent() + { + GenericScope parent = getParent(); + if (parent != null) + variables().putAll((Map) parent.variables()); + return this; + } + + /** + * @param scope | GenericScope whose content will be added! + * + * @return This scope... + * + * @since 1.3.0 + */ + public GenericScope addAll(GenericScope scope) + { + values().addAll(scope.values()); + variables().putAll(scope.variables()); + return this; + } + + /** + * @return Entry set of variables! + * + * @since 1.2.0 + */ + public Set> varEntrySet() + { + return variables().entrySet(); + } + + /** + * @return Count of keyless values of this scope! (values().size()) + * + * @since 1.2.0 + */ + public int valuesCount() + { + return values().size(); + } + + /** + * @return Count of variables! (variables().size()) + * + * @since 1.2.0 + */ + public int variablesCount() + { + return variables().size(); + } + + /** + * @return Total number of variables and independent values of this scope! (vvaluesCount() + variablesCount()) + */ + public int totalSize() + { + return valuesCount() + variablesCount(); + } + + /** + * @return True if this scope is completely empty, meaning there are no variables or values. + * + * @since 1.2.0 + */ + public boolean isEmpty() + { + return totalSize() <= 0; + } + + /** + * @return The parent scope of this scope or null if this scope has no parent such as default one in file. + * + * @since 1.2.0 + */ + public GenericScope getParent() + { + return getParent(false); + } + + /** + * @param absoluteParent | If true, absolute parent of this scope will be returned (parent of parent of parent...)! + * + * @return The parent scope of this scope or null if this scope has no parent such as default one in file. + * + * @since 1.3.2 + */ + public GenericScope getParent(boolean absoluteParent) + { + if (!absoluteParent) + return parent; + GenericScope parent = this.parent; + for (GenericScope tmpPar; parent != null && (tmpPar = parent.getParent()) != null; parent = tmpPar); + return parent; + } + + /** + * @return New {@link LinkedHashMap} with variables of this a in defined order! Key is a KeyT of variable and value is its value!
+ * Modifying this map will not affect this GenericScope object! + * + * @since 1.2.0 + */ + public LinkedHashMap toVarMap() + { + return new LinkedHashMap<>(variables()); + } + + /** + * @return New {@link ArrayList} with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this GenericScope object! + * + * @since 1.2.0 + */ + public List toValList() + { + return new ArrayList<>(values()); + } + + /** + * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this {@link GenericScope} object! + * + * @since 1.2.0 + */ + public Object[] toValArray() + { + return values().toArray(); + } + + /** + * @param vals | Array to store independent values into! + * + * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this {@link GenericScope} object! + * + * @since 1.3.5 + */ + public V[] toValArray(V[] vals) + { + return values().toArray(vals); + } + + /** + * @return List with both variables and values! Variables will be added as {@link Entry}! + * Variables will be always first! + * Modifying this map will not affect this GenericScope object! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public List toUnifiedList() + { + List list = (List) toValList(); + list.addAll(0, varEntrySet()); + return list; + } + + /** + * @return Values of this scope. These are not the values of keys these are values that have no key. You can access them via {@link GenericScope#get(int)}! + * Note: Editing this List will affect this scope! + * + * @since 1.2.0 + */ + public List values() + { + if (values == null) + values = new ArrayList<>(); + return values; + } + + /** + * @return Variables of this scope. Objecthis variables has nothing to do with values. Key is a KeyT name of variable and value is value of variable. + * Note: Editing this Map will affect this scope! + * + * @since 1.2.0 + */ + public Map variables() + { + if (variables == null) + variables = new LinkedHashMap<>(); + return variables; + } + + /** + * @param variablesMap | Variables map to use! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap) + { + return newBidirectional(variablesMap, null); + } + + /** + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap, List values) + { + return newBidirectional(variablesMap, values, null); + } + + /** + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * @param parent | Parent of scope! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap, List values, GenericScope parent) + { + return intoBidirectional(new GenericScope<>(null, null, null), variablesMap, values, parent); + } + + /** + * @param scopeToMakeBidirectional | GenericScope to make bidirectional! + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * + * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope intoBidirectional(GenericScope scopeToMakeBidirectional, Map variablesMap, List values) + { + return intoBidirectional(scopeToMakeBidirectional, variablesMap, values, null); + } + + /** + * @param scopeToMakeBidirectional | GenericScope to make bidirectional! + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * @param parent | Parent of scope! + * + * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope intoBidirectional(GenericScope scopeToMakeBidirectional, Map variablesMap, List values, GenericScope parent) + { + scopeToMakeBidirectional.variables = variablesMap; + scopeToMakeBidirectional.values = values; + scopeToMakeBidirectional.parent = parent; + return scopeToMakeBidirectional; + } + + /** + * @param map | Map to populate from kV array. + * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... + * + * @return Same map populated with kV array. + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public static Map mapKvArray(Map map, Object... kVkVkV) + { + for (int i = 1; i < kVkVkV.length; i+=2) + map.put((K) kVkVkV[i-1], (V) kVkVkV[i]); + return map; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java new file mode 100644 index 0000000..05e85fd --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java @@ -0,0 +1,864 @@ +package org.ugp.serialx; + +import static org.ugp.serialx.converters.DataParser.VOID; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.File; +import java.io.Flushable; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.ObjectConverter; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.converters.imports.ImportConverter; +import org.ugp.serialx.converters.operators.ArithmeticOperators; +import org.ugp.serialx.converters.operators.ComparisonOperators; +import org.ugp.serialx.converters.operators.ConditionalAssignmentOperators; +import org.ugp.serialx.converters.operators.LogicalOperators; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + +import javafx.beans.binding.When; + +/** + * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! + * It should generate and work with .juss or .srlx files! + * + * @author PETO + * + * @since 1.3.2 + */ +@SuppressWarnings("serial") +public class JussSerializer extends Serializer +{ + public static final ParserRegistry JUSS_PARSERS = DataParser.REGISTRY.clone(), JUSS_PARSERS_AND_OPERATORS; + + static + { + JUSS_PARSERS.add(0, new ImportConverter()); + JUSS_PARSERS_AND_OPERATORS = JUSS_PARSERS.clone(); + JUSS_PARSERS_AND_OPERATORS.addAllBefore(StringConverter.class, true, new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators()); + } + + /** + * Set this on true and program will generate comments and report!
+ * Note: Keep this on false to achieve the best performance! + * + * @since 1.0.5 + */ + protected boolean generateComments = false; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public JussSerializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Map variablesMap, Collection values) + { + this(null, variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, null, variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public JussSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(parsers, protocols, variablesMap, values, parent); + } + + @Override + public Scope clone() + { + Scope scope = super.clone(); + if (scope instanceof JussSerializer) + { + ((JussSerializer) scope).setGenerateComments(isGenerateComments()); + ((JussSerializer) scope).setParsers(getParsers()); + ((JussSerializer) scope).setProtocols(getProtocols()); + } + return scope; + } + + @Override + public JussSerializer emptyClone(Scope parent) + { + JussSerializer srl = emptyClone(new JussSerializer(), parent); + srl.setGenerateComments(isGenerateComments()); + return srl; + } + + @Override + public ParserRegistry getParsers() + { + return parsers != null ? parsers : (parsers = JUSS_PARSERS.clone()); + } + + /** + * @param absoluteClone | If true this scope will be cloned using {@link Serializer#Clone(Object, Registry, Object[], Object...)}, if false {@link Scope#clone()}! + * + * @return Clone of this scope! + * + * @since 1.3.2 + */ + public Scope clone(boolean absoluteClone) + { + if (absoluteClone) + return Clone(this, getParsers(), new Object[] {-9999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return super.clone(); + } + + /** + * @param name | Name of variable. + * @param value | Value of variable. + * + * @return Variable in JUSS form to serialize as [name] = [value]. + * + * @since 1.1.5 + */ + @Override + public String Var(String name, T value) + { + return Var(name, value, false); + } + + /** + * @param name | Name of variable. + * @param value | Value of variable. + * @param isValue | True if variables value supposed to by visible also during value loading. + * + * @return Variable in JUSS form to serialize as [name] = [value]. + * + * @since 1.1.5 + */ + public String Var(String name, T value, boolean isValue) + { + return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), isGenerateComments()) + (generateComments ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + } + + /** + * @param cls | Class to invoke static member on! + * @param staticMethodName | Name of static member! + * @param args | Arguments of method (use this only if you are invoking method no field)! + * + * @return Static member invocation in JUSS form to serialize as [class]::[method | field] [args]... + *

Note: This will not invoke member from class directly, it will be invoked during unserialization, also no checks are performed here so this will not notify you if member or class does not exist!
+ * Also this will work only in combination {@link ObjectConverter}! + * + * @since 1.2.2 + */ + public String StaticMember(Class cls, String staticMethodName, Object... args) + { + StringBuilder sb = new StringBuilder(); + for (int i = 0, len = args.length; i < len; i++) + sb.append(getParsers().toString(args[i], 0, 0, this, getProtocols(), isGenerateComments())).append(i < len-1 ? " " : ""); + return Code(cls.getName() + "::" + staticMethodName + (args.length <= 0 ? "" : " ") + sb); + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param args | Additional arguments to use, in case of {@link JussSerializer} this should be array of length 6 with 0. argument being this pointer to this serializer, argument 1. and 2. being integers signifying number of tabs and index of parsing iteration (used primarily by {@link ObjectConverter}), argument 3. containing {@link ProtocolRegistry} of this {@link Serializer}, argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}), and argument 5. being boolean signifying whether or not code comments are supposed to be generated! + * + * @return Source {@link Appendable} with variables and objects serialized in specific format. + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + @Override + public A SerializeTo(A source, Object... args) throws IOException + { + Map variables = variables(); + List objs = values(); + int valuesLen = objs.size(), varLen = variables.size(), i = 0, tabs = 0; + + if (args.length < 6) + args = Arrays.copyOf(args, 6); + args[0] = this; + if (args[1] == null) + args[1] = tabs; //tabs + else if (args[1] instanceof Integer) + tabs = (int) args[1]; + if (args[2] == null) + args[2] = 0; //index + if (args[3] == null) + args[3] = getProtocols(); + if (args[5] == null) + args[5] = isGenerateComments(); + + source = source == null ? (A) new StringBuilder() : source; + if (generateComments && varLen + valuesLen > 0) //Gen scope comment + { + if (tabs <= 0) + source.append("//Date created: ").append(new SimpleDateFormat("MM-dd-yyyy 'at' HH:mm:ss z \n\n").format(new Date())); + source.append(multilpy('\t', tabs)).append("//Scope serialization summary:\n"); + if (varLen > 0) + source.append(multilpy('\t', tabs)).append("//").append(varLen+"").append(" variables!\n"); + + if (valuesLen > 0) + source.append(multilpy('\t', tabs)).append("//").append(valuesLen+"").append(" values!\n"); + if (tabs > -1) + source.append('\n'); + } + + ParserRegistry reg = getParsers(); + + if (varLen > 0) + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); + if (generateComments && (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty())) + GenerateComment(source, reg, var); + + if (i++ < varLen-1 || valuesLen > 0) + source.append('\n'); + } + } + + for (i = 0; i < valuesLen; i++) //Values + { + Object obj = objs.get(i); + CharSequence serialized = reg.toString(obj, args); + + appandVal(source, serialized, obj, tabs, i >= valuesLen-1); + if (generateComments && (!(obj instanceof Scope) || ((Scope) obj).isEmpty())) + GenerateComment(source, reg, obj); + + if (i < valuesLen-1) + source.append('\n'); + } + + if (source instanceof Flushable) + ((Flushable) source).flush(); + if (tabs == 0) + getImports().removeImportsOf(this); + return source; + } + + /** + * This should append serializedVar into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException + { + source.append(multilpy('\t', tabs)).append(serializedVar); + if (isLast && var.getValue() instanceof Scope) + return source; + return source.append(';'); + } + + /** + * This should append serializedVal into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException + { + source.append(multilpy('\t', tabs)).append(serializedVal); + if (isLast && value instanceof Scope || serializedVal != null && indexOfNotInObj(serializedVal, '/') != -1) + return source; + return source.append(';'); + } + + /** + * @return Generated description for obj, appended in source! + * + * @since 1.3.2 + */ + public Appendable GenerateComment(Appendable source, ParserRegistry registry, Object obj) throws IOException + { + try + { + CharSequence comment = registry.getConverterFor(obj).getDescription(registry, obj); + if (comment.length() > 0) + return source.append(" //").append(comment); + } + catch (Exception e) + { + return source.append(" //").append(DataConverter.getDefaultDescriptionFor(obj)); + } + return source; + } + + /** + * @param reader | Reader to read from! + * @param formatingArgs | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this scope (it can be also boolean signifying if formating is required), 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, and additional argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}). + * + * @return This scope after loading data from reader (you most likely want to return "this")! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + @Override + public S LoadFrom(Reader reader, Object... args) + { + boolean formatRequired = true; + + if (args.length < 4) + args = Arrays.copyOf(args, 4); + if (args[0] instanceof Boolean) + formatRequired = (boolean) args[0]; + args[0] = this; + if (args[3] == null) + args[3] = getProtocols(); + + String str = readAndFormat(reader, formatRequired); + List objs = splitAndParse(str, 0, args); + addAll(objs); + + //double t0 = System.nanoTime(); + /*Registry reg = DataParser.REGISTRY; + String lastLine = null; + int quote = 0, multLineCom = -1, brackets = 0; + try + { + BufferedReader lineReader = new BufferedReader(reader); + //String blanks = new String(new char[] {32, 9, 10, 12, 13}); + for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) + { + for (int i = 0, len = line.length(), com = -1, lastIndex = 0; i < len; i++) + { + char ch = line.charAt(i); + if (ch == '/' && i < len-1 && line.charAt(i+1) == '/') + com++; + else if (multLineCom <= -1 && ch == '"') + quote++; + + boolean notString = quote % 2 == 0; + if (multLineCom > -1 || com > -1) //Is comment + { + if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') + com = multLineCom = -1; + } + else if (notString && ch == '/' && i < len-1 && line.charAt(i+1) == '*') + i += multLineCom = 1; + /*else if (notString && blanks.indexOf(ch) > -1) + { + if ((chBefore = i > 0 ? line.charAt(i-1) : 0) != ';' && chBefore != '{' && blanks.indexOf(chBefore) <= -1) + sb.append(" "); + }*/ + /*else if (notString && i < str.length()-1 && (ch == '!' && str.charAt(i+1) == '!' || ch == '-' && str.charAt(i+1) == '-' || ch == '+' && str.charAt(i+1) == '+')) + i++;* + else + { + if (notString) + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + line); + } + else if (brackets == 0 && (ch == ';' || ch == ',')) + { + //System.out.println(lastIndex + " " + i); + String str = line.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i); + //System.out.println(str); + if (!(str = str.trim()).isEmpty()) + { + Object obj = ParseObjectHandleNull(reg, str, true, result); + if (obj != VOID) + result.add(obj); + } + } + } + } + } + lastLine = line; + } + lineReader.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + //double t = System.nanoTime(); + //System.out.println((t-t0)/1000000); + + if (lastLine != null && indexOfNotInObj(lastLine, ';', ',') <= -1) + { + if (!(lastLine = lastLine.trim()).isEmpty()) + { + Object obj = ParseObjectHandleNull(reg, lastLine, true, result); + if (obj != VOID) + result.add(obj); + } + }*/ + + if (parent == null) + getImports().removeImportsOf(this); + else + for (Map.Entry ent : parent.varEntrySet()) + if (variables().get(ent.getKey()) == ent.getValue()) + variables().remove(ent.getKey()); + return (S) this; + } + + /** + * @return Formated content of reader ready to parse! + * + * @since 1.3.2 + */ + protected String readAndFormat(Reader reader, boolean format) + { + int quote = 0, multLineCom = -1; + //int brackets = 0, lastIndex = 0, delChars = 0; + StringBuilder sb = new StringBuilder(); + + try + { + BufferedReader lineReader = new BufferedReader(reader); + //String blanks = new String(new char[] {32, 9, 10, 12, 13}); + for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) + { + if (format) + { + int lastNotBlank = -1; + for (int i = 0, com = -1, len = line.length(); i < len; i++) + { + char ch = line.charAt(i); + + boolean notString = quote % 2 == 0; + if (multLineCom > -1 || com > -1) //Is comment + { + if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') + com = multLineCom = -1; + } + else if (notString && ch == '/' && i < len-1) + { + if (line.charAt(i+1) == '*') + i += multLineCom = 1; + else if (line.charAt(i+1) == '/') + com++; + else + sb.append('/'); + } + else if (notString && ch >= 9 && ch <= 13) + sb.append(' '); + else + { + /*if (notString) + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + line); + } + else if (brackets == 0 && isOneOf(ch, ';', ',')) + { + System.out.println(sb); + sb = new StringBuilder(); + continue; + } + }*/ + if (ch > 32) + { + lastNotBlank = ch; + if (ch == '"') + quote++; + } + sb.append(ch); + } + } + sb.append(lastNotBlank == '}' || lastNotBlank == ']' ? ';' : ' '); + } + else + sb.append(line).append('\n'); + } + lineReader.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + return sb.toString(); + } + + /** + * @return List of objects parsed from given formatted string! + * + * @since 1.3.2 + */ + protected List splitAndParse(String formattedStr, int offset, Object... parserArgs) + { + List result = new ArrayList<>(); + + ParserRegistry reg = getParsers(); + + //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; + int brackets = 0, quote = 0, lastIndex = 0; + //boolean isBracketSplit = false; + for (int i = 0, len = formattedStr.length(); i < len; i++) + { + char ch = formattedStr.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + /*if (isBracketSplit) + add = 0; + isBracketSplit = false;*/ + if (brackets == 0 && (ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) + { + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/); + if (!(str = str.trim()).isEmpty()) + { + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); + } + //add = 1; + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + formattedStr); + } + } + } + + if (quote % 2 != 0) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); + else if (brackets > 0) + throw new IllegalArgumentException("Unclosed brackets in: " + formattedStr); + else + { + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, formattedStr.length()); + if (!(str = str.trim()).isEmpty()) + { + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); + } + } + + return result; + } + +// /** +// * @return Object converted to string! +// *

+// * Note: Used by {@link JussSerializer#SerializeTo(Appendable, Object...)}! +// * +// * @see DataConverter#objToString(Registry, String, Object...) +// * +// * @since 1.3.5 +// */ +// public CharSequence objectToStr(Registry registry, Object obj, Object... parserArgs) +// { +// return +// } + + /** + * @return Object parsed from str! + *

+ * Note: Used by {@link JussSerializer#splitAndParse(String, int, Object...)}! + * + * @see DataParser#parseObj(Registry, String, Object...) + * + * @since 1.3.2 + */ + protected Object parseObject(ParserRegistry registry, String str, Object... parserArgs) + { + return NULL.toOopNull(registry.parse(str, parserArgs)); + } + + /** + * @param variable | Variable to clone! + * + * @return Clone of value stored by variable with inserted name or null if there is no such a one! + *

+ * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * + * @since 1.3.2 + */ + public T cloneOf(String variableName) + { + return cloneOf(variableName, null); + } + + /** + * @param variable | Variable to clone! + * @param defaultValue | Default value to return. + * + * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one! + *

+ * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * + * @since 1.3.2 + */ + public T cloneOf(String variableName , T defaultValue) + { + T obj = get(variableName , defaultValue); + if (obj == defaultValue) + return defaultValue; + return Serializer.Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Clone of independent value with valueIndex! + *

+ * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * + * @since 1.3.2 + */ + public T cloneOf(int valueIndex) + { + T obj = get(valueIndex); + return Serializer.Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + } + + /** + * @return True if comment supposed to be generated! + * + * @since 1.3.2 + */ + public boolean isGenerateComments() + { + return generateComments; + } + + /** + * @param generateComments | If true, comments will be generated during serialization! + * + * @since 1.3.2 + */ + public void setGenerateComments(boolean generateComments) + { + this.generateComments = generateComments; + } + +// /** +// * @return True if used parsers and converters are cached during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! +// * +// * @since 1.3.5 +// * +// * @see ParserRegistry#resetCache() +// */ +// public boolean isSerializationAutoCaching() +// { +// return serializationAutoCaching; +// } +// +// /** +// * @param serializationAutoCaching | Set this on true to allow caching of used parsers and converters during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! +// * +// * @since 1.3.5 +// * +// * @see ParserRegistry#resetCache() +// * @see ParserRegistry#destroyCache() +// */ +// public void setSerializationAutoCaching(boolean serializationAutoCaching) +// { +// if (!(this.serializationAutoCaching = serializationAutoCaching)) +// getParsers().destroyCache(); +// } + + /** + * @param fromObj | Object to create serializer from! + * + * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JussSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#LoadFrom(CharSequence)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#LoadFrom(File)}
{@link Reader}{@link Serializer#LoadFrom(Reader)}
{@link InputStream}{@link Serializer#LoadFrom(InputStream)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws When something went wrong during deserialization! + * + * @since 1.3.5 + */ + public static JussSerializer from(Object fromObj) throws Exception + { + try + { + return from(fromObj, new String[0]); + } + catch (IntrospectionException e) + { + return new JussSerializer(fromObj); + } + } + + /** + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JussSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#LoadFrom(CharSequence)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#LoadFrom(File)}
{@link Reader}{@link Serializer#LoadFrom(Reader)}
{@link InputStream}{@link Serializer#LoadFrom(InputStream)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + public static JussSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return (JussSerializer) Serializer.from(new JussSerializer(), fromObj, fieldNamesToUse); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java new file mode 100644 index 0000000..79c3039 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java @@ -0,0 +1,63 @@ +package org.ugp.serialx; + +/** + * Log provider used for logging in SerialX. + * You can use to to easily implement log4j or other logging utilities. + * + * @author PETO + * + * @since 1.3.5 + */ +public class LogProvider +{ + protected boolean reThrowException; + + public static LogProvider instance = new LogProvider(); + + /** + * @param object | Object to log in normal mode! + * + * @since 1.3.5 + */ + public void logOut(Object object) + { + System.out.println(object); + } + + /** + * @param object | Object to log in error mode! + * @param ex | Exception that cause the error! + * + * @since 1.3.5 + */ + public void logErr(Object obj, Throwable ex) + { + if (reThrowException) + { + if (ex == null) + throw new RuntimeException(obj.toString()); + throw new RuntimeException(ex); + } + System.err.println(obj); + } + + /** + * @return If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! + * + * @since 1.3.5 + */ + public boolean isReThrowException() + { + return reThrowException; + } + + /** + * @param reThrowException | If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! + * + * @since 1.3.5 + */ + public void setReThrowException(boolean reThrowException) + { + this.reThrowException = reThrowException; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java new file mode 100644 index 0000000..ba26bc7 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java @@ -0,0 +1,404 @@ +package org.ugp.serialx; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * This is list that can contains only one element per class! Trying to add 2 elements with same class will cause old one to be removed and new one will be added! + * + * @author PETO + * + * @param | The type of elements held in this collection + * + * @since 1.3.0 + */ +public class Registry extends ArrayList +{ + private static final long serialVersionUID = 1L; + + /** + * Constructs an {@link Registry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.0 + */ + public Registry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link Registry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.0 + */ + public Registry(Collection c) + { + super(c); + } + + /** + * Constructs an {@link Registry} with objs. + * + * @param objs | Initial content of registry. + * + * @since 1.3.0 + */ + @SafeVarargs + public Registry(E... objs) + { + addAll(objs); + } + + @Override + public Registry clone() + { + return new Registry<>(this); + } + + @Override + public boolean addAll(Collection c) + { + return addAll(size(), c); + } + + @Override + public boolean addAll(int index, Collection c) + { + for (E s : c) + add(index++, s); + return true; + } + + @Override + public boolean add(E e) + { + add(size(), e); + return true; + } + + @SuppressWarnings("unchecked") + @Override + public void add(int index, E element) + { + E contained = get((Class) element.getClass()); + if (contained != null) + remove(contained); + super.add(index, element); + } + + /** + * @param exclude | Class of elements to exclude! + * + * @return Clone of this registry, excluding elements of inserted classes! + * + * @since 1.3.0 + */ + public Registry clone(Class... exclude) + { + Registry clone = clone(); + + for (int i = clone.size() - 1; i >= 0; i--) + { + E e = clone.get(i); + for (Class cls : exclude) + if (e.getClass() == cls) + clone.remove(e); + } + return clone; + } + + /** + * Similar to regular add however this one will not remove existing element if duplicate (should not be public)! + * Essentially it will simply do super.add(index, element)! + * + * @param index | Index at which the specified element is to be inserted! + * @param element | Element to add! + * + * @since 1.3.0 + */ + protected void addDuplicatively(int index, E element) + { + super.add(index, element); + } + + /** + * @param elms | Array o elements to add! + * + * @return {@link Registry#addAll(int, Object...)} + * + * @since 1.3.0 + */ + public void addAll(@SuppressWarnings("unchecked") E... elms) + { + addAll(size(), elms); + } + + /** + * @param elms | Array o elements to add! + * + * @return {@link Registry#addAll(int, Collection)} + * + * @since 1.3.0 + */ + public void addAll(int index, @SuppressWarnings("unchecked") E... elms) + { + for (E s : elms) + add(index++, s); + } + + /** + * @param elm | Class of element to add! + * + * @return Instantiated obj of inserted class that was added. Empty constructor required! + * + * @throws Exception + * + * @since 1.3.0 + */ + public E add(Class elm) throws Exception + { + E inst = elm.getConstructor().newInstance(); + add(inst); + return inst; + } + + /** + * @param elms | Array of classes to be instantiated and added! + * + * @throws Exception + * + * @since 1.3.0 + */ + public void addAll(@SuppressWarnings("unchecked") Class... elms) throws Exception + { + for (Class cls : elms) + add(cls); + } + + /** + * @param cls | Class to find! + * @param element | Element to insert before index of required class! + * + * @since 1.3.0 + */ + public void addBefore(Class cls, E element) + { + addBefore(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert before index of required class! + * + * @since 1.3.0 + */ + public void addBefore(Class cls, boolean includeChildrens, E element) + { + int index = indexOf(cls); + if (index <= -1) + add(element); + else + add(index, element); + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element) + { + addAllBefore(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAllBefore(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + { + int index = indexOf(cls); + if (index <= -1) + addAll(element); + else + addAll(index, element); + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAfter(Class cls, E element) + { + addAfter(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAfter(Class cls, boolean includeChildrens, E element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + add(element); + else + add(index + 1, element); + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAllAfter(Class cls, @SuppressWarnings("unchecked") E... element) + { + addAllAfter(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @since 1.3.0 + */ + public void addAllAfter(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + addAll(element); + else + addAll(index + 1, element); + } + + /** + * @param cls | Class to get instance for! + * + * @return Element of class or null if there is no such a one! + * + * @since 1.3.0 + */ + public C get(Class cls) + { + return get(cls, false); + } + + /** + * @param cls | Class to get instance for! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Element of class according to includeChildrens flag or null if there is no such a one! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public C get(Class cls, boolean includeChildrens) + { + C obj = null; + for (int i = 0, size = size(); i < size; i++) + { + C elm = (C) get(i); + Class objCls = elm.getClass(); + if (objCls == cls) + return elm; + else if (includeChildrens && cls.isAssignableFrom(objCls)) + obj = elm; + } + return obj; + } + + /** + * @param cls | Instances class to get index of! + * + * @return Index of element with required class or -1 if there is no such a one! + * + * @since 1.3.0 + */ + public int indexOf(Class cls) + { + return indexOf(cls, false); + } + + /** + * @param cls | Instances class to get index of! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Index of element with class according to includeChildrens flag or -1 if there is no such a one! + * + * @since 1.3.0 + */ + public int indexOf(Class cls, boolean includeChildrens) + { + int index = -1; + for (int i = 0; i < size(); i++) + { + Class objCls = get(i).getClass(); + if (objCls == cls) + return i; + else if (includeChildrens && cls.isAssignableFrom(objCls)) + index = i; + } + return index; + } + + /** + * @param cls | Class of element to remove! + * + * @return Removed element itself! + * + * @since 1.3.0 + */ + public E remove(Class cls) + { + return remove(cls, false); + } + + + /** + * @param cls | Class of element to remove! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Removed element itself or null if there is no element with cls! + * + * @since 1.3.0 + */ + public E remove(Class cls, boolean includeChildrens) + { + int i = indexOf(cls, includeChildrens); + if (i > -1) + return remove(i); + return null; + } + + + /** + * @param newContent | New content to set, old one will be deleted! + * + * @return Registry with previous content! + * + * @since 1.3.0 + */ + public Registry setTo(Registry newContent) + { + Registry old = clone(); + clear(); + addAll(newContent); + return old; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java new file mode 100644 index 0000000..baa1551 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -0,0 +1,1285 @@ +package org.ugp.serialx; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Array; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Map.Entry; +import java.util.function.Predicate; + +import org.ugp.serialx.converters.ArrayConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + + +/** + * This is some kind of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
+ * Note: Variables are managed and accessed classically via {@link Map} methods such as put(String key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
+ * Also this is java representation of JUSS Scope group such as: + *
+ * 
+ * {
+ *     //This is scope in JUSS!
+ * }
+ * 
+ * 
+ * + * @author PETO + * + * @since 1.2.0 and since 1.3.5 splitted to {@link Scope} and {@link GenericScope} + */ +public class Scope extends GenericScope +{ + private static final long serialVersionUID = 4693418156224566721L; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.5 + */ + @SafeVarargs + public Scope(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.5 + */ + @SafeVarargs + public Scope(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : Arrays.asList(values)); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.5 + */ + public Scope(Map variablesMap, Collection values) + { + this(variablesMap, values, null); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public Scope(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param | Parent of this scope. + + * @since 1.3.5 + */ + public Scope(Map variablesMap, Collection values, GenericScope parent) + { + super(variablesMap, values, parent); + } + + @Override + public Scope clone() + { + return (Scope) super.clone(); + } + + /** + * @param variableName | Variables name. + * + * @return Byte value of variable with name or 0 if there is no such a one! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public byte getByte(String variableName) + { + return getByte(variableName, (byte) 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Byte value of variable with name or defaultValue if there is no such a one! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public byte getByte(String variableName, byte defaultValue) + { + return (byte) getInt(variableName, defaultValue); + } + + /** + * @param variableName | Variables name. + * + * @return Byte value of variable with name or 0 if there is no such a one! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public short getShort(String variableName) + { + return getShort(variableName, (short) 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Byte value of variable with name or defaultValue if there is no such a one! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public short getShort(String variableName, short defaultValue) + { + return (short) getInt(variableName, defaultValue); + } + + /** + * @param variableName | Variables name. + * + * @return Int value of variable with name or 0 if there is no such a one! + * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public int getInt(String variableName) + { + return getInt(variableName, 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Int value of variable with name or defaultValue if there is no such a one! + * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public int getInt(String variableName, int defaultValue) + { + return (int) getLong(variableName, defaultValue); + } + + /** + * @param variableName | Variables name. + * + * @return Long value of variable with name or 0 if there is no such a one! + * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public int getLong(String variableName) + { + return getInt(variableName, 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Long value of variable with name or defaultValue if there is no such a one! + * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public long getLong(String variableName, long defaultValue) + { + return (long) getDouble(variableName, defaultValue); + } + + /** + * @param variableName | Variables name. + * + * @return Float value of variable with name or 0 if there is no such a one! + * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public float getFloat(String variableName) + { + return getFloat(variableName, 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Float value of variable with name or defaultValue if there is no such a one! + * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public float getFloat(String variableName, float defaultValue) + { + return (float) getDouble(variableName, defaultValue); + } + + /** + * @param variableName | Variables name. + * + * @return Double value of variable with name or 0 if there is no such a one! + * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public double getDouble(String variableName) + { + return getDouble(variableName, 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Double value of variable with name or defaultValue if there is no such a one! + * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public double getDouble(String variableName, double defaultValue) + { + Object obj = get(variableName, defaultValue); + if (obj instanceof Number) + return ((Number) obj).doubleValue(); + else if (obj instanceof Character) + return (double) (char) obj; + else if (obj instanceof CharSequence) + return Double.parseDouble(obj.toString()); + return (double) obj; + } + + /** + * @param variableName | Variables name. + * + * @return String value of variable with name or null if there is no such a one! + * String will be also parsed from any object using {@link Object#toString()}! + * + * @since 1.2.5 + */ + public String getString(String variableName) + { + return getString(variableName, null); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return String value of variable with name or defaultValue if there is no such a one! + * String will be also parsed from any object using {@link Object#toString()}! + * + * @since 1.2.5 + */ + public String getString(String variableName, String defaultValue) + { + Object obj = get(variableName, defaultValue); + return obj == null ? null : obj.toString(); + } + + /** + * @param variableName | Variables name. + * + * @return Char value of variable with name or {@code (char) 0} if there is no such a one! + * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public char getChar(String variableName) + { + return getChar(variableName, (char) 0); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Char value of variable with name or defaultValue if there is no such a one! + * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public char getChar(String variableName, char defaultValue) + { + Object obj = get(variableName, defaultValue); + if (obj instanceof Character) + return (char) obj; + else if (obj instanceof CharSequence) + return ((CharSequence) obj).charAt(0); + else if (obj instanceof Number) + return (char) ((Number) obj).intValue(); + return (char) obj; + } + + /** + * @param variableName | Variables name. + * + * @return Boolean value of variable with name or false if there is no such a one! + * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public boolean getBool(String variableName) + { + return getBool(variableName, false); + } + + /** + * @param variableName | Variables name. + * @param defaultValue | Default value to return. + * + * @return Boolean value of variable with name or defaultValue if there is no such a one! + * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public boolean getBool(String variableName, boolean defaultValue) + { + Object obj = get(variableName, defaultValue); + if (obj instanceof Boolean) + return (boolean) obj; + else if (obj instanceof Number) + return ((Number) obj).doubleValue() > 0; + else + { + String str = obj.toString(); + if (str.equalsIgnoreCase("t")) + return true; + else if (str.equalsIgnoreCase("f")) + return false; + return Boolean.parseBoolean(obj.toString()); + } + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent byte value with valueIndex. + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public byte getByte(int valueIndex) + { + return (byte) getInt(valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent short value with valueIndex. + * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public short getShort(int valueIndex) + { + return (short) getInt(valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent int value with valueIndex. + * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public int getInt(int valueIndex) + { + return (int) getLong(valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent long value with valueIndex. + * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public long getLong(int valueIndex) + { + return (long) getDouble(valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent float value with valueIndex. + * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public float getFloat(int valueIndex) + { + return (float) getDouble(valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent double value with valueIndex. + * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public double getDouble(int valueIndex) + { + Object obj = get(valueIndex); + if (obj instanceof Number) + return ((Number) obj).doubleValue(); + else if (obj instanceof Character) + return (double) (char) obj; + else if (obj instanceof CharSequence) + return Double.parseDouble(obj.toString()); + return (double) obj; + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent string value with valueIndex. + * String will be also parsed from any object using {@link Object#toString()}! + * + * @since 1.2.5 + */ + public String getString(int valueIndex) + { + Object obj = get(valueIndex); + return obj == null ? null : obj.toString(); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent char value with valueIndex. + * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public char getChar(int valueIndex) + { + Object obj = get(valueIndex); + if (obj instanceof Character) + return (char) obj; + else if (obj instanceof CharSequence) + return ((CharSequence) obj).charAt(0); + else if (obj instanceof Number) + return (char) ((Number) obj).intValue(); + return (char) obj; + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent boolean value with valueIndex. + * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible! + * + * @since 1.2.5 + */ + public boolean getBool(int valueIndex) + { + Object obj = get(valueIndex); + if (obj instanceof Boolean) + return (boolean) obj; + else if (obj instanceof Number) + return ((Number) obj).doubleValue() > 0; + else + { + String str = obj.toString(); + if (str.equalsIgnoreCase("t")) + return true; + else if (str.equalsIgnoreCase("f")) + return false; + return Boolean.parseBoolean(obj.toString()); + } + } + + /** + + + * @param scopeValueIndex | Index of sub-scopes value. + * + * @return Sub-scope on required index or null if there is no scope on required index!
+ * Note: Keep in mind that you need to insert valid index according to other values. Scopes share same index order with other values! + * + * @since 1.2.0 + */ + public Scope getScope(int scopeValueIndex) + { + try + { + return (Scope) this.getGenericScope(scopeValueIndex); + } + catch (ClassCastException e) + { + return null; + } + } + + /** + * @param scopesOrderIndex | Order index of sub-scope. + * + * @return Sub-scope with required number. Similar to {@link Scope#getScope(int)} however this will ignore non scope values. + *

+ * For instance getSubScope(1) in context:
+ *
+	 * 
+	 * variable = "something";
+	 * "something";
+	 * {
+	 *      "Scope0"
+	 * };
+	 * 123;
+	 * null;
+	 * {
+	 *      "Scope1" <- This one will be returned!
+ * }; + * 4; + * 5; + * 6; + * { + * "Scope2" + * } + *
+ *
+ * + * @since 1.2.0 + */ + public Scope getSubScope(int subscopesOrderIndex) + { + for (int i = 0, j = 0; i < valuesCount(); i++) + { + Scope scope = getScope(i); + if (scope != null && j++ == subscopesOrderIndex) + return scope; + } + return null; + } + + /** + * @param scopesPath | Array with variable names creating path to required scope. + * + * @return Sub-scope stored by variable with required name (last element) in inserted path or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! + * This search will also includes sub-scopes of scope but variables from lower ones are prioritize!
+ * If this function is called with no arguments then self will be returned! + *
+ *
+	 * 
+	 * variable = "something";
+	 * scope1 = 
+	 * {
+	 *      subScope = 
+	 *      {
+	 *          scopeObjectoFind = {...}; <- this one will be returned if getScope("scope1", "scopeObjectoFind") is issued!
+	 *          7;...
+	 *      }
+	 * };
+	 * scopeObjectoFind = {...} <- this one will be returned if getScope("scopeObjectoFind") is issued!
+	 * 
+	 * 
+ * Note: Remember that this search includes variables only, no values! + * + * @since 1.2.0 + */ + public Scope getScope(String... scopesPath) + { + try + { + return (Scope) getGenericScope(scopesPath); + } + catch (ClassCastException e) + { + return null; + } + } + + /** + * @param scopesValueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * @param objClass | Object of class to create. + * + * @return Object of objClass constructed from independent value with scopesValueIndex! If there is no Scope stored at scopesValueIndex this function behaves same as {@link GenericScope#get(int)}! + * If independent value is {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. + * Note: Scopes are searched via regular independent value index no scope index like {@link Scope#getScope(int)}. + * + * @see Serializer#PROTOCOL_REGISTRY + * @see GenericScope#toObject(Class) + * + * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public T toObjectOf(int scopesValueIndex, Class objClass) throws Exception + { + Object obj = get(scopesValueIndex); + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(objClass); + return (T) obj; + } + + /** + * @param variableWithScope | Variable that supposed to contains scope. + * @param objClass | Object of class to create. + * + * @return Value of variable with name or null if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! + * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. + * + * @see Serializer#PROTOCOL_REGISTRY + * @see GenericScope#toObject(Class) + * + * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + public T toObjectOf(String variableWithscope, Class objClass) throws Exception + { + return toObjectOf(variableWithscope, objClass, null); + } + + /** + * @param variableWithScope | Variable that supposed to contains scope. + * @param objClass | Object of class to create. + * @param defaultValue | Default value to return. + * + * @return Value of variable with name or defaultValue if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! + * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. + * + * @see Serializer#PROTOCOL_REGISTRY + * @see GenericScope#toObject(Class) + * + * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + public T toObjectOf(String variableWithscope, Class objClass, T defaultValue) throws Exception + { + return toObjectOf(variableWithscope, objClass, defaultValue, SerializationProtocol.REGISTRY); + } + + /** + * @param variableWithScope | Variable that supposed to contains scope. + * @param objClass | Object of class to create. + * @param defaultValue | Default value to return. + * @param protocolsToUse | Registry of protocols to use. + * + * @return Value of variable with name or defaultValue if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! + * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. + * + * @see Serializer#PROTOCOL_REGISTRY + * @see GenericScope#toObject(Class) + * + * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public T toObjectOf(String variableWithscope, Class objClass, T defaultValue, ProtocolRegistry protocolsToUse) throws Exception + { + T obj = get(variableWithscope, defaultValue); + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(objClass, protocolsToUse); + return obj; + } + + /** + * @param varName | Variable with name to search! + Expected generic type of possible results, {@link ClassCastException} will be thrown is some variable contains value that can't be cast to this! + * + * @return Values stored by variable with inserted name collected from this scope! + * + * @since 1.3.0 + */ + public List getAllStoredBy(String varName) + { + return getAllStoredBy(varName, true); + } + + /** + * @param varName | Variable with name to search! + * @param includeSubScopes | If true, this search will include sub-scopes as well (variables are iterated first values second)! + * Expected generic type of possible results, {@link ClassCastException} will be thrown is some variable contains value that can't be cast to this! + * + * @return Values stored by variable with inserted name collected from this scope! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public List getAllStoredBy(String varName, boolean includeSubScopes) + { + List result = new ArrayList<>(); + + for (Entry var : varEntrySet()) + if (var.getKey().equals(varName)) + result.add((V) var.getValue()); + else if (includeSubScopes && var.getValue() instanceof Scope) + result.addAll(((Scope) var.getValue()).getAllStoredBy(varName, includeSubScopes)); + + for (Object object : this) + if (object instanceof Scope) + result.addAll(((Scope) object).getAllStoredBy(varName, includeSubScopes)); + + return result; + } + + /** + * @param varName | Variable with name to search! + * @param value | Value of variable to search! + * + * @return Scope containing all sub-scopes of this scope that contains variable with required name that is set to required value! + * + * @since 1.3.2 + */ + public Scope getScopesWith(String varName, Object value) + { + return getScopesWith(varName, value, true); + } + + /** + * @param varName | Variable with name to search! + * @param value | Value of variable to search! + * @param includeSubScopes | If true, this search will include sub-scopes as well (variables are iterated first values second)! + * + * @return Scope containing all sub-scopes of this scope that contains variable with required name that is set to required value! + * + * @since 1.3.2 + */ + public Scope getScopesWith(String varName, Object value, boolean includeSubScopes) + { + return getScopesWith(varName, obj -> Objects.deepEquals(obj, value)); + } + + /** + * @param varName | Variable with name to search! + * @param condition | Condition that will be tested for value of each variable! + * + * @return Scope containing all sub-scopes of this scope that contains variable which meets inserted condition! + * + * @since 1.3.2 + */ + public Scope getScopesWith(String varName, Predicate condition) + { + return getScopesWith(varName, condition, true); + } + + /** + * @param varName | Variable with name to search! + * @param condition | Condition that will be tested for value of each variable! + * @param includeSubScopes | If true, this search will include sub-scopes as well (variables are iterated first values second)! + * + * @return Scope containing all sub-scopes of this scope that contains variable which meets inserted condition! + * + * @since 1.3.2 + */ + public Scope getScopesWith(String varName, Predicate condition, boolean includeSubScopes) + { + Scope result = new Scope(null, null, getParent()); + + for (Entry myVar : varEntrySet()) + if (myVar.getValue() instanceof Scope) + try + { + Scope scope = (Scope) myVar.getValue(); + if (scope.containsVariable(varName) && condition.test(scope.get(varName))) + result.add(scope); + else if (includeSubScopes) + result.addAll(scope.getScopesWith(varName, condition, includeSubScopes)); + } + catch (ClassCastException e) + {} + for (Object object : this) + if (object instanceof Scope) + try + { + Scope scope = (Scope) object; + if (scope.containsVariable(varName) && condition.test(scope.get(varName))) + result.add(scope); + else if (includeSubScopes) + result.addAll(scope.getScopesWith(varName, condition, includeSubScopes)); + } + catch (ClassCastException e) + {} + return result; + } + + /** + * @param objClass | Object of class to create using protocols. + * @param protocolsToUse | Registry of protocols to use. + * + * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * If there were no suitable deserialization protocols found, {@link Scope#into(Class, String...)} will be used! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @see Scope#into(Class, String...) + * @see Scope#intoNew(Class, GenericScope, String...) + * + * @since 1.3.5 + */ + public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception + { + T obj = super.toObject(objClass, protocolsToUse); + if (obj != null) + return obj; + + try + { + return into(objClass); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to create new instance of " + objClass.getName() + " because none of provided protocols were suitable and class introspection has failed as well!", e); + return null; + } + } + + /** + * @param objCls | Class of object to instantiate! + * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! PropertyDescriptors of these fields will be obtained using Scope.getPropertyDescriptorsOf(Class, String)! This is used only as a last (default) option! + * + * @return New instance of object according to {@link GenericScope#intoNew(Class, GenericScope, String...)} similarly to {@link GenericScope#toObject(Class)} except this one will not use any protocols! + * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! + * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! + * + * @see Scope#intoNew(Class, GenericScope, String...) + * + * @since 1.3.5 + */ + public T into(Class objCls, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return (T) intoNew(objCls, this, fieldNamesToUse); + } + + /** + * @param obj | Object to map this scopes variables into! + * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! PropertyDescriptors of these fields will be obtained using Scope.getPropertyDescriptorsOf(Class, String)! This is used only as a last (default) option! + * + * @return New instance of object according to {@link GenericScope#intoNew(Class, GenericScope, String...)} similarly to {@link GenericScope#toObject(Class)} except this one will not use any protocols! + * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! + * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! + * + * @see Scope#intoNew(Class, GenericScope, String...) + * + * @since 1.3.5 + */ + public T into(Object obj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return into(obj, this, fieldNamesToUse); + } + + /** + * @param obj | Object to create scope from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return Scope created from given obj by mapping obj's fields into variables of created scope via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> Scope conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (obj) typeObtained scope (return)
nullnew Scope<>()
{@link Array} (primitive)Array elements will become independent values of new scope
{@link GenericScope}Clone of scope {@link GenericScope#clone()}
{@link Collection}Element of collection will become independent values of new scope
{@link Map}Entries of map will become variables of new scope
Others (default){@link Scope#from(Object, List)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s read method fails! + * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static Scope from(Object obj, String... fieldNamesToUse) throws Exception, IntrospectionException + { + if (obj == null) + return new Scope(); + + if (obj.getClass().isArray()) + return new Scope(ArrayConverter.fromAmbiguous(obj)); + + if (obj instanceof Scope) + { + Scope scope = ((Scope) obj).clone(); + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + scope.variables().keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return scope; + } + + if (obj instanceof Collection) + return new Scope(null, (Collection) obj); + + if (obj instanceof Map) + { + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + ((Map) obj).keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return new Scope((Map) obj, (Collection) null); + } + + return from(obj, getPropertyDescriptorsOf(obj.getClass(), fieldNamesToUse)); + } + + /** + * @param obj | Object to create scope from! + * @param fieldsToUse | List of {@link PropertyDescriptor}s representing fields of object to map into scopes variables using getters (read method)! + * + * @return Scope created from given obj by mapping obj's fields into variables of created scope via given {@link PropertyDescriptor}s (fieldsToUse)! + * + * @throws Exception if calling of some {@link PropertyDescriptor}s read method fails (should not happen often)! + * + * @since 1.3.5 + */ + public static Scope from(Object obj, List fieldsToUse) throws Exception + { + return from(new Scope(), obj, fieldsToUse); + } + + /** + * @param newInstance | New instance of specific {@link Scope}! + * @param obj | Object to create scope from! + * @param fieldsToUse | List of {@link PropertyDescriptor}s representing fields of object to map into scopes variables using getters (read method)! + * + * @return Scope (newInstance) structured from given obj by mapping obj's fields into variables of created scope via given {@link PropertyDescriptor}s (fieldsToUse)! + * + * @throws Exception if calling of some {@link PropertyDescriptor}s read method fails (should not happen often)! + * + * @since 1.3.5 + */ + public static Scope from(Scope newInstance, Object obj, List fieldsToUse) throws Exception + { + //if (variablesToUse != null) + //variablesToUse = AutoProtocol.getPropertyDescriptorsOf(obj.getClass()); + for (PropertyDescriptor var : fieldsToUse) + newInstance.put(var.getName(), var.getReadMethod().invoke(obj)); + return newInstance; + } + + /** + * @param objCls | Class of object to instantiate! + * @param fromScope | Source scope with data to instantiate from! + * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return Instantiated object populated/mapped with required variables of fromScope (fieldNamesToUse) and conversion rules listed below! {@link Serializer#Instantiate(Class)} will be used for object instantiation!

+ * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Class/type (objCls)New object instance (return)
nullnull
{@link Array} (primitive)New primitive array populated with all independent values of fromScope
{@link GenericScope}Clone of fromScope
{@link Collection}New collection instance with all independent values of fromScope
{@link Map}New map instance with all variables of fromScope
Others (default){@link Scope#into(Object, GenericScope, List)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! + * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static T intoNew(Class objCls, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception + { + if (objCls == null) + return null; + + if (objCls.isArray()) + { + if (objCls.getComponentType() == Object.class) + return (T) fromScope.toValArray(); + + return (T) into(Array.newInstance(objCls.getComponentType(), fromScope.valuesCount()), fromScope, fieldNamesToUse); + } + + if (GenericScope.class.isAssignableFrom(objCls)) + { + GenericScope result = ((GenericScope) fromScope).clone((Class>)objCls); + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + result.variables().keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return (T) result; + } + + if (objCls.isInterface()) + { + if (Collection.class.isAssignableFrom(objCls)) + { + return (T) fromScope.toValList(); + } + + if (Map.class.isAssignableFrom(objCls)) + { + Map map = fromScope.toVarMap(); + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + map.keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return (T) map; + } + } + + return into(Serializer.Instantiate(objCls), fromScope, fieldNamesToUse); + } + + /** + * @param obj | Object to map scopes variables into! + * @param fromScope | Source scope with variables to use for mapping! + * @param fieldNamesToUse | Array of obj field names to map/populate from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return Same obj after being populated/mapped by variables of given scope via requested fields (fieldNamesToUse) and conversion rules listed below!

+ * Table of specific Scope --> Object conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (obj) typeAction with obj (return)
nullnull
{@link Array} (primitive)Independent values of fromScope will be injected into array
{@link GenericScope}Content of fromScope will be added into Scope
{@link Collection}Independent values of fromScope will be added to Collection
{@link Map}Variables of fromScope will be added to Map
Others (default){@link Scope#into(Object, GenericScope, List)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! + * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static T into(Object obj, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception + { + if (obj == null) + return null; + if (obj.getClass().isArray()) + { + for (int i = 0, arrLen = Array.getLength(obj), scSize = fromScope.valuesCount(); i < arrLen && i < scSize; i++) + Array.set(obj, i, fromScope.get(i)); + return (T) obj; + } + + if (obj instanceof GenericScope) + { + ((GenericScope) obj).addAll(fromScope); + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + ((GenericScope) obj).variables().keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return (T) obj; + } + + if (obj instanceof Collection) + { + ((Collection) obj).addAll(fromScope.values()); + return (T) obj; + } + + if (obj instanceof Map) + { + ((Map) obj).putAll(fromScope.variables()); + if (fieldNamesToUse != null && fieldNamesToUse.length > 0) + ((Map) obj).keySet().retainAll(Arrays.asList(fieldNamesToUse)); + return (T) obj; + } + + return (T) into(obj, fromScope, getPropertyDescriptorsOf(obj.getClass(), fieldNamesToUse)); + } + + /** + * @param obj | Object to map scopes variables into! + * @param fromScope | Source scope with variables to use for mapping! + * @param fieldsToUse | List of {@link PropertyDescriptor}s representing fields of object to map/populate from scopes variables using setters (write method)! + * + * @return Same obj after being populated/mapped by variables of given scope via requested {@link PropertyDescriptor}s (fieldsToUse)! + * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static T into(T obj, GenericScope fromScope, List fieldsToUse) throws Exception + { + for (PropertyDescriptor var : fieldsToUse) + { + Object varValue = ((GenericScope) fromScope).get(var.getName(), DataParser.VOID); + if (varValue != DataParser.VOID) + var.getWriteMethod().invoke(obj, varValue); + } + return obj; + } + + /** + * @param cls | Class to inspect! + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! + * + * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! + * + * @throws IntrospectionException when there are no suitable fields with valid and public getters and setters. + * + * @see PropertyDescriptor + * + * @since 1.3.5 + */ + public static List getPropertyDescriptorsOf(Class cls, String... fieldNames) throws IntrospectionException + { + return getPropertyDescriptorsOf(cls, null, fieldNames); + } + + + /** + * @param cls | Class to inspect! + * @param cache | Cache to store generated results into! + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! + * + * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! + * + * @throws IntrospectionException when there are no suitable fields with valid and public getters and setters. + * + * @see PropertyDescriptor + * + * @since 1.3.5 + */ + public static List getPropertyDescriptorsOf(Class cls, Map, List> cache, String... fieldNames) throws IntrospectionException + { + List fieldDescriptors = new ArrayList<>(), cached = cache == null ? null : cache.get(cls); + if (cached != null) + return cached; + + if (fieldNames == null || fieldNames.length <= 0) + { + for (Class c = cls; c != Object.class; c = c.getSuperclass()) + for (Field field : c.getDeclaredFields()) + if (!Modifier.isStatic(field.getModifiers())) + try + { + fieldDescriptors.add(new PropertyDescriptor(field.getName(), cls)); + } + catch (Exception e) + {} + + if (cache != null && !fieldDescriptors.isEmpty()) + { + cache.put(cls, fieldDescriptors); + } + } + else + { + for (int i = 0; i < fieldNames.length; i++) + try + { + fieldDescriptors.add(new PropertyDescriptor(fieldNames[i], cls)); + } + catch (Exception e) + {} + } + + if (fieldDescriptors.isEmpty()) + throw new IntrospectionException("No suitable fields with valid and public getters and setters to use in " + cls.getSimpleName()); + return fieldDescriptors; + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java b/SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java new file mode 100644 index 0000000..e19307c --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java @@ -0,0 +1,400 @@ +package org.ugp.serialx; + +import java.util.Arrays; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; + +/** + * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
+ * During parsing, type __debug or __debug_yourObject into your code!
+ * During converting/serializing, serialize your object using {@link DebugWrapper} with your object as argument! + * + * @author PETO + * + * @since 1.3.5 + */ +public class SerializationDebugger implements DataConverter +{ + public static final String DEBUG_MARK = new String("__debug"); + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + synchronized (this) { + if (str.toLowerCase().startsWith(DEBUG_MARK)) + return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); + return CONTINUE; + } + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof DebugWrapper) + return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), ((DebugWrapper) obj).obj, null, args).toString(); + return CONTINUE; + } + + /** + * Print and return debug results of parsing or converting! + * + * @return Parsed object or object converted to string! + * + * @since 1.3.5 + */ + public Object printDebugs(DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) + { + String action = objToSerialize == null && strToParse != null ? "Parsing" : "Converting"; + System.err.println("--------------------------------------------- " + action + " Debug ---------------------------------------------"); + if (args == null) + System.err.println("------- Available args (args): none (args = null)!"); + else + print("------- Available args (args):", Arrays.asList(args), 0); + + if (myHomeRegistry == null) + System.err.println("\n------- Available parsers (myHomeRegistry: null): none!"); + else + print("\n------- Available parsers (myHomeRegistry: " + myHomeRegistry.getClass().getName() + "):", myHomeRegistry, 0); + + if (strToParse != null && (strToParse = strToParse.substring(DEBUG_MARK.length())).length() > 0 && (strToParse = strToParse.substring(1)).length() > 0) + { + if (args.length < 100) + { + myHomeRegistry.getRegistryIterationStackTrace().clear(); + args = Arrays.copyOf(args, 100); + args[99] = 0; + } + else if (args[99] instanceof Integer && (int) args[99] > 0) + { + myHomeRegistry = myHomeRegistry.clone(); + myHomeRegistry.iterationStackTrace = new TreeMap<>(); + } + + double t0 = System.nanoTime(); + objToSerialize = myHomeRegistry.parse(strToParse, args); + double t = System.nanoTime(); + + if (myHomeRegistry.getParsingCache() == null) + System.err.println("\n------- Paring cache (after process): null (none)"); + else + print("\n------- Paring cache (after process):", Arrays.asList(myHomeRegistry.getParsingCache()), 0); + print("\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + System.err.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + System.err.println("String \"" + strToParse + "\" was parsed into:\n\t" + toStringAndCls(objToSerialize)); + System.err.println("\n"); + return objToSerialize; + } + + if (objToSerialize != null) + { + if (args.length < 100) + { + myHomeRegistry.getRegistryIterationStackTrace().clear(); + args = Arrays.copyOf(args, 100); + args[99] = 0; + } + else if (args[99] instanceof Integer && (int) args[99] > 0) + { + myHomeRegistry = myHomeRegistry.clone(); + myHomeRegistry.iterationStackTrace = new TreeMap<>(); + } + + double t0 = System.nanoTime(); + strToParse = myHomeRegistry.toString(objToSerialize, args).toString(); + double t = System.nanoTime(); + + if (myHomeRegistry.getConverterCache() == null) + System.err.println("\n------- Converting cache (after process): null (none)"); + else + print("\n------- Converting cache (after process):", Arrays.asList(myHomeRegistry.getConverterCache()), 0); + print("\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + System.err.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + System.err.println("Object " + toStringAndCls(objToSerialize) + " was converted to string:\n" + (strToParse.contains("\n") ? strToParse : "\t" + strToParse)); + System.err.println("\n"); + return strToParse; + } + + if (myHomeRegistry.getParsingCache() == null) + System.err.println("\n------- Current parsing cache: null (none)"); + else + print("\n------- Current parsing cache:", Arrays.asList(myHomeRegistry.getParsingCache()), 0); + + if (myHomeRegistry.getConverterCache() == null) + System.err.println("\n------- Current parsing cache: null (none)"); + else + print("\n------- Current parsing cache:", Arrays.asList(myHomeRegistry.getConverterCache()), 0); + System.err.println("\n--------------------------------------------- No Results ---------------------------------------------"); + System.err.println("\n"); + return VOID; + } + + /** + * @param serializer | Serializer to debug! + * + * @return Serializer capable of debugging its serialization and deserialization! + * + * @since 1.3.5 + */ + public static T debug(T serializer) + { + return debug(serializer, new SerializationDebugger()); + } + + /** + * @param serializer | Serializer to debug! + * @param debuger | Specific debugger to use! + * + * @return Serializer capable of debugging its serialization and deserialization! + * + * @since 1.3.5 + */ + public static T debug(T serializer, SerializationDebugger debugger) + { + serializer.getParsers().add(0, debugger); + serializer.setParsers(new DebugParserRegistry(serializer.getParsers())); + return serializer; + } + + /** + * @param objToSerializeAndDebug | Object you want to serialize and see the debug of serialization! + * + * @return Object wrapped for debugger to debug! + * + * @since 1.3.5 + */ + public static DebugWrapper wrapForDebug(Object objToSerializeAndDebug) + { + return new DebugWrapper(objToSerializeAndDebug); + } + + /** + * @return obj + " (" + obj.getClass().getName() + ")" + * Note: Used internally by debugger! + * + * @since 1.3.5 + */ + public static String toStringAndCls(Object obj) + { + if (obj == null) + return "null"; + else + return obj + " (" + obj.getClass().getName() + ")"; + } + + /** + * This will print list into console in somewhat more readable form with tabs and introduction text! + * + * @since 1.3.5 + */ + public static void print(String text, List objs, int tabs) + { + System.err.println(text); + for (int i = 0, i2 = 0; i < objs.size(); i++) + { + Object o = objs.get(i); + String strTbs = Serializer.multilpy('\t', tabs).toString(); + if (o instanceof List) + print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + else if (o instanceof Map) + print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + else + System.err.println(Serializer.multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); + } + } + + /** + * This will print map into console in somewhat more readable form with tabs and introduction text! + * + * @since 1.3.5 + */ + public static void print(String text, Map map, int tabs) + { + System.err.println(text); + for (Entry entry : map.entrySet()) + { + Object o = entry.getValue(); + String strTbs = Serializer.multilpy('\t', tabs).toString(); + if (o instanceof List) + print(strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + else if (o instanceof Map) + print(strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + else + System.err.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); + } + } + + /** + * Use this during converting/serializing! + * + * @author PETO + * + * @since 1.3.5 + * + * @see SerializationDebugger + */ + protected static class DebugWrapper + { + public final Object obj; + + /** + * @param yourObject | Your object to serialize in debug mode! + * + * @since 1.3.5 + */ + public DebugWrapper(Object yourObject) + { + obj = yourObject; + } + } + + /** + * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! + * + * @author PETO + * + * @since 1.3.5 + */ + public static class DebugParserRegistry extends ParserRegistry + { + /** + * + */ + private static final long serialVersionUID = 3445967263611388142L; + + protected Map iterationStackTrace = new TreeMap<>(); + + public DebugParserRegistry(ParserRegistry registry) + { + super(registry); + resetCache(registry.getParsingCache(), registry.getConverterCache()); + } + + @Override + public DebugParserRegistry clone() + { + DebugParserRegistry reg = new DebugParserRegistry(this); + reg.iterationStackTrace = this.iterationStackTrace; + return reg; + } + + @Override + public CharSequence toString(Object obj, Object... args) { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + CharSequence str = null; + if (convertingCache != null) + for (int i = 0; i < convertingCache.length; i++) + { + DataParser parser = convertingCache[i]; + if (parser != null) + { + double t0 = System.nanoTime(); + str = ((DataConverter) parser).toString(this, obj, args); + double t = System.nanoTime(); + if (str != CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return str; + } + } + } + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (parser instanceof DataConverter) + { + double t0 = System.nanoTime(); + str = ((DataConverter) parser).toString(this, obj, args); + double t = System.nanoTime(); + if(str != CONTINUE) + { + if (convertingCache != null && i < convertingCache.length) + convertingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return str; + } + } + } + + LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + return null; + } + + @Override + public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) + { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + Object obj = null; + if (parsingCache != null) + for (int i = 0; i < parsingCache.length; i++) + { + DataParser parser = parsingCache[i]; + if (parser != null) + { + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + toStringAndCls(obj)); + return obj; + } + } + } + + registryLoop: for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (ignore != null) + for (Class cls : ignore) + if (cls == parser.getClass()) + continue registryLoop; + + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + toStringAndCls(obj)); + return obj; + } + } + + if (returnAsStringIfNotFound) + return str; + + LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + return null; + } + + /** + * @return Ordered map of registry iterations generated by using it during parsing or converting! + * + * @since 1.3.5 + */ + public Map getRegistryIterationStackTrace() + { + return iterationStackTrace; + } + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java new file mode 100644 index 0000000..6c0fe08 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -0,0 +1,1880 @@ +package org.ugp.serialx; + +import static org.ugp.serialx.converters.DataParser.VOID; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import org.ugp.serialx.converters.BooleanConverter; +import org.ugp.serialx.converters.CharacterConverter; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.NullConverter; +import org.ugp.serialx.converters.NumberConverter; +import org.ugp.serialx.converters.SerializableBase64Converter; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.converters.imports.ImportConverter; +import org.ugp.serialx.converters.imports.ImportConverter.Imports; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + +/** + * {@link org.ugp.serialx.Serializer} is powerful utility class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s. + * This class itself is responsible for utility, formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage! + * It is instance of {@link Scope} so we can say that this is scope that can serialize itself using system of already mentioned {@link DataParser} and {@link SerializationProtocol}! + * + * @author PETO + * + * @since 1.0.0 + */ +@SuppressWarnings("serial") +public abstract class Serializer extends Scope implements ImportsProvider +{ + /** + * Common parsers that can parse primitive datatypes! + * + * @since 1.3.2 + */ + public static final ParserRegistry COMMON_PARSERS = new ParserRegistry(new StringConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + + protected ParserRegistry parsers; + protected ProtocolRegistry protocols; + protected Imports imports; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public Serializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Map variablesMap, Collection values) + { + this(null, variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, null, variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public Serializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(variablesMap, values, parent); + if (parsers != null) + setParsers(parsers); + if (protocols != null) + setProtocols(protocols); + } + + @Override + public Scope clone() + { + try + { + return clone(getClass()); + } + catch (Exception e) + { + return new JussSerializer(variables(), values(), getParent()); + } + } + + @Override + public > S clone(Class typeOfClone) throws Exception + { + S clone = super.clone(typeOfClone); + if (clone instanceof Serializer) + { + ((Serializer) clone).setParsers(getParsers()); + ((Serializer) clone).setProtocols(getProtocols()); + } + return clone; + } + + @Override + public > S castTo(Class newType) throws Exception + { + S clone = super.castTo(newType); + if (clone instanceof Serializer) + { + ((Serializer) clone).setParsers(getParsers()); + ((Serializer) clone).setProtocols(getProtocols()); + } + return clone; + } + + @Override + public T toObjectOf(String variableWithscope, Class objClass, T defaultValue) throws Exception + { + return toObjectOf(variableWithscope, objClass, defaultValue, getProtocols()); + } + + @Override + public T toObject(Class objClass) throws Exception + { + return toObject(objClass, getProtocols()); + } + + /** + * @see Serializer#into(Object, Serializer, String...) + */ + @Override + public T into(Object obj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return Serializer.into(obj, this, fieldNamesToUse); + } + + @Override + public Imports getImports() + { + if (imports == null) + imports = ImportConverter.IMPORTS.clone(); + return imports; + } + + /** + * @param name | Name of variable. + * @param value | Value of variable. + * + * @return Classic variable expression in general form like [name] = [value]. + * + * @since 1.1.5 + */ + public String Var(String name, T value) + { + return Code(name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), false) + ";"); + } + + /** + * @param comment | The comment... + * + * @return Comment in general form, such as //comment
Each line will be taken as new comment! + * + * @since 1.1.5 + */ + public String Comment(String comment) + { + StringBuilder sb = new StringBuilder(); + String[] lines = comment.split("\n"); + for (int i = 0; i < lines.length; i++) + sb.append("//" + lines[i] + (i < lines.length - 1 ? "\n" : "")); + return Code(sb); + } + + /** + * + * @param code | Code to convert into JUSS (StringConverter) code form. + * @return "${" + code + "} + *

Note: This works only in combination with {@link StringConverter}! + * + * @since 1.1.5 + * + * @see StringConverter#DirectCode(Object) + */ + public String Code(Object code) + { + return StringConverter.DirectCode(code); + } + + /** + * @param serialize | If true, this scope will be serialized to string! + * + * @return This scope as string! + * + * @since 1.3.2 + * + * @see Serializer#Stringify(Object...) + */ + public String toString(boolean serialize) throws IOException + { + if (serialize) + return Stringify(); + return super.toString(); + } + + /** + * @param f | File to write in. This must be a text file. + * + * @return String with variables and objects serialized in specific format. + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + */ + public void SerializeTo(File f) throws IOException + { + SerializeTo(false, f); + } + + /** + * @param append | When true, the new objects will be appended to files content (same objects will be also appended if there are some)! + * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return String with variables and objects serialized in specific format. + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + * + * @see Serializer#SerializeTo(Appendable, Object...) + */ + public void SerializeTo(boolean append, File f, Object... args) throws IOException + { + //double t0 = System.nanoTime(); + BufferedWriter writer = new BufferedWriter(new FileWriter(f, append)); + + writer.write(Stringify(args)); + + writer.close(); + } + + /** + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return String with objects serialized in specific format. + * + * @since 1.0.0 + * + * @see Serializer#SerializeTo(Appendable, Object...) + */ + public String Stringify(Object... args) throws IOException + { + return SerializeTo(new StringBuilder(), args).toString(); + } + + /** + * @param source | Source {@link OutputStream} to serialize variables and objects into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link OutputStream} with variables and objects serialized in specific format (may or may not be flushed). + * + * @since 1.3.2 + * + * @see Serializer#SerializeTo(Appendable, Object...) + */ + public OutputStream SerializeTo(OutputStream outputStream, Object... args) throws IOException + { + SerializeTo(new OutputStreamWriter(outputStream), args); + return outputStream; + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link Appendable} with variables and objects serialized in specific format. + * + * @since 1.3.2 + */ + public abstract A SerializeTo(A source, Object... args) throws IOException; + + /** + * @param file | Text file with serialized objects in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. + * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! + * + * @throws FileNotFoundException if file does not exist! + * + * @since 1.0.0 + * + * @see Serializer#LoadFrom(Reader, Object...) + */ + public S LoadFrom(File file, Object... parserArgs) throws FileNotFoundException + { + return LoadFrom(new FileReader(file), parserArgs); + } + + /** + * @param str | {@link CharSequence} with serialized objects in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. + * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! + * + * @since 1.2.5 + * + * @see Serializer#LoadFrom(Reader, Object...) + */ + public S LoadFrom(CharSequence str, Object... parserArgs) + { + return LoadFrom(new StringReader(str.toString()), parserArgs); + } + + /** + * @param stream | Any {@link InputStream} with serialized objects in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. + * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! + * + * @since 1.3.2 + * + * @see Serializer#LoadFrom(Reader, Object...) + */ + public S LoadFrom(InputStream stream, Object... parserArgs) + { + return LoadFrom(new InputStreamReader(stream), parserArgs); + } + + /** + * @param reader | Any {@link Reader} with serialized objects in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. + * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! + * + * @since 1.2.5 + */ + public S LoadFrom(Reader reader) + { + return LoadFrom(reader, true); + } + + /** + * @param reader | Reader to read from! + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return This scope after loading data from reader (you most likely want to return "this")! + * + * @since 1.3.2 + */ + public abstract S LoadFrom(Reader reader, Object... parserArgs); + + /** + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @since 1.3.2 + */ + public Serializer emptyClone() throws Exception + { + return emptyClone(this); + } + + /** + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @since 1.3.2 + */ + public Serializer emptyClone(Scope parent) throws Exception + { + return emptyClone(getClass(), parent); + } + + /** + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @since 1.3.5 + */ + public T emptyClone(Class typeOfClone, GenericScope parent) throws Exception + { + return emptyClone(Instantiate(typeOfClone), parent); + } + + /** + * @param newEmptyInstance | Manually inserted brand new empty instance of this scope! + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @since 1.3.5 + */ + public T emptyClone(T newEmptyInstance, GenericScope parent) + { + newEmptyInstance.setParsers(getParsers()); + newEmptyInstance.setProtocols(getProtocols()); + newEmptyInstance.parent = parent; + return newEmptyInstance; + } + + /** + * @return {@link Registry} with parsers that this {@link Serializer} uses! + * + * @since 1.3.2 + */ + public ParserRegistry getParsers() + { + if (parsers == null) + parsers = COMMON_PARSERS.clone(); + return parsers; + } + + /** + * @param parsers | Registry with parsers to set! + * + * @since 1.3.2 + */ + public void setParsers(Registry parsers) + { + setParsers(parsers instanceof ParserRegistry ? (ParserRegistry) parsers : new ParserRegistry(parsers)); + } + + /** + * @param parsers | Registry with parsers to set! + * + * @since 1.3.5 + */ + public void setParsers(ParserRegistry parsers) + { + this.parsers = (ParserRegistry) parsers; + } + + /** + * @return {@link ProtocolRegistry} with serialization protocols that this {@link Serializer} uses! + * + * @since 1.3.2 + */ + public ProtocolRegistry getProtocols() + { + if (protocols == null) + protocols = SerializationProtocol.REGISTRY.clone(); + return protocols; + } + + /** + * @param protocols | ProtocolRegistry with serialization protocols to set! + * + * @since 1.3.2 + */ + public void setProtocols(ProtocolRegistry protocols) + { + this.protocols = protocols; + } + + /** + * @param parser | DataParser to add! + * + * @return DataParser if was added! + * + * @since 1.3.2 + */ + public DataParser addParser(DataParser parser) + { + if (getParsers().add(parser)) + return parser; + return null; + } + + /** + * @param protocol | SerializationProtocol to add! + * + * @return SerializationProtocol if was added! + * + * @since 1.3.2 + */ + public SerializationProtocol addProtocol(SerializationProtocol protocol) + { + if (getProtocols().add(protocol)) + return protocol; + return null; + } + + /** + * This will transform this Serializer and whole tree of its sub-scopes into regular {@link Scope}s! + * Remember that scope is just a data container and analyzer and it can't be serialized in contrast to serializer! + * + * @return This serializer transformed in to simple {@link Scope}! + * + * @since 1.3.2 + */ + public GenericScope transformToScope() + { + Function transFunction = new Function() + { + @Override + public Object apply(Object t) + { + if (t instanceof Serializer) + { + GenericScope srl = ((Scope) t).transform(this); + return new GenericScope<>(srl.variables(), srl.values(), srl.getParent()); + } + return t; + } + }; + return (GenericScope) transform(transFunction); + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized content of this scope as inner sub-scope of this scope! Wrapped inside of corresponding wrappingBrackets (default { and })! + * + * @since 1.3.5 + */ + public A SerializeAsSubscope(A source, Object... args) throws IOException + { + return SerializeAsSubscope(source, new char[] {'{', '}'}, args); + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param wrappingBrackets | Array of 2 characters to wrap content inside + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized content of this scope as inner sub-scope of this scope! Wrapped inside of corresponding wrappingBrackets (default { and })! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public A SerializeAsSubscope(A source, char[] wrappingBrackets, Object... args) throws IOException + { + int tabs = 0; + if (args.length > 1 && args[1] instanceof Integer) + { + tabs = (int) args[1]; + args[1] = tabs + 1; + } + source.append(wrappingBrackets[0]); + if (!isEmpty()) + source = (A) SerializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)); + return (A) source.append(wrappingBrackets[1]); + } + + /* + * @param file | File with specific format content. + * @param index | Index of value to get from lowest Scope. + * + * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(file).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! + * But target value can't be using any variables declared outside and also can't be variable invocation itself! Also there might be some problems with commented code! Also there can't be no variables in file! + * + * @since 1.2.5 + * + @Deprecated + public T LoadFrom(File file, int index) + { + try + { + return LoadFrom(new FileReader(file), index); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + return null; + } + + /** + * @param str | Any {@link CharSequence} with specific format content. + * @param index | Index of value to get from lowest Scope. + * + * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(str).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! + * But target value can't be using any variables declared outside and also can't be variable invocation itself! Also there might be some problems with commented code! + * + * @since 1.2.5 + * + @Deprecated + public T LoadFrom(CharSequence str, int index) + { + return LoadFrom(new StringReader(str.toString()), index); + } + + /** + * @param reader | Any {@link Reader} with specific format content. + * @param index | Index of value to get from lowest Scope. + * + * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(reader).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! + * But target value can't be using any variables declared outside and also can't be variable invocation itself! + * + * @since 1.2.5 + * + @Deprecated + @SuppressWarnings("unchecked") + public T LoadFrom(Reader reader, int index) + { + StringBuilder sb = new StringBuilder(); + int semicolon = 0, brackets = 0, quote = 0, vars = 0, multLineCom = -1; + + String line; + try + { + BufferedReader lineReader = new BufferedReader(reader); + while ((line = lineReader.readLine()) != null) + { + if (!contains(line = line.trim(), '=', ':') || !(brackets == 0 && quote % 2 == 0)) + for (int i = 0, com = -1, len = line.length(); i < len; i++) + { + char ch = line.charAt(i); + + if (ch == '/' && i < len-1 && line.charAt(i+1) == '/') + com++; + else if (multLineCom <= -1 && ch == '"') + quote++; + + boolean notInObj = brackets == 0 && quote % 2 == 0; + if (semicolon > index) + { + lineReader.close(); + return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, sb.toString(), this)); + } + + if (multLineCom > -1 || com > -1) //Is comment + { + if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') + multLineCom = -1; + } + else if (ch == '/' && i < len-1) + { + char chNext = line.charAt(i+1); + if (chNext == '*') + i += multLineCom = 1; + else + sb.append(ch); + } + /*else if (notInObj && ch == '=') + { + vars++; + }* + else if (notInObj && isOneOf(ch, ';', ',')) + { + if (vars > 0) + { + vars = 0; + } + else + semicolon++; + } + else + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + { + lineReader.close(); + throw new IllegalArgumentException("Missing closing bracket in: " + line); + } + } + + if (vars == 0 && semicolon == index) + sb.append(ch); + } + } + else + { + char lastCh = line.charAt(line.length()-1); + if (isOneOf(lastCh, '{', '[')) + brackets++; + if (isOneOf(lastCh, ';', ',')) + vars++; + } + + } + } + catch (IOException e) + { + e.printStackTrace(); + } + + if (brackets > 0) + throw new IllegalArgumentException("Unclosed brackets!"); + else if (quote % 2 != 0) + throw new IllegalArgumentException("Unclosed or missing quotes!"); + else if (!(line = sb.toString()).isEmpty()) + return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, line, this)); + LogProvider.instance.logErr("Value with index " + index + " is out of bounds!"); + return null; + } + + /** + * @param file | File with specific format content. + * @param varName | Name of variable to load! + * + * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(file).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! + * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! + * + * @since 1.2.5 + * + @Deprecated + public T LoadFrom(File file, String varName) + { + try + { + return LoadFrom(new FileReader(file), varName); + } + catch (FileNotFoundException e) + { + e.printStackTrace(); + } + return null; + } + + /** + * @param str | Any {@link CharSequence} with specific format content. + * @param varName | Name of variable to load! + * + * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(str).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! + * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! + * + * @since 1.2.5 + * + @Deprecated + public T LoadFrom(CharSequence str, String varName) + { + return LoadFrom(new StringReader(str.toString()), varName); + } + + /** + * @param reader | Any {@link Reader} with specific format content. + * @param varName | Name of variable to load! + * + * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(reader).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! + * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! + * + * @since 1.2.5 + * + @Deprecated + @SuppressWarnings("unchecked") + public T LoadFrom(Reader reader, String varName) + { + StringBuilder sb = new StringBuilder(); + int brackets = 0, quote = 0, multLineCom = -1, fromIndex = 0, fromIndexOrig = 0, findIndex = -1; + + String line; + try + { + BufferedReader lineReader = new BufferedReader(reader); + while ((line = lineReader.readLine()) != null) + { + if (findIndex <= -1 && multLineCom <= -1 && line.length() > varName.length() && !(line.charAt(0) == '/' && isOneOf(line.charAt(1), '/', '*')) && (findIndex = line.indexOf(varName)) > -1) + { + fromIndexOrig = fromIndex = findIndex; + findIndex+=sb.length(); + } + + for (int com = -1, len = line.length(); fromIndex < len; fromIndex++) + { + char ch = line.charAt(fromIndex); + + if (ch == '/' && fromIndex < len-1 && line.charAt(fromIndex+1) == '/') + com++; + else if (multLineCom <= -1 && ch == '"') + quote++; + + if (findIndex > -1 && quote % 2 == 0 && brackets == 0 && isOneOf(ch, ';', ',')) + { + lineReader.close(); + int start = sb.indexOf("=", findIndex-fromIndexOrig); + if (start <= -1) + start = sb.indexOf(":", findIndex-fromIndexOrig); + return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, sb.substring(start+1), this)); + } + + if (multLineCom > -1 || com > -1) //Is comment + { + if (multLineCom > 0 && ch == '*' && fromIndex < len-1 && line.charAt(++fromIndex) == '/') + multLineCom = -1; + } + else if (ch == '/' && fromIndex < len-1) + { + char chNext = line.charAt(fromIndex+1); + if (chNext == '*') + fromIndex = multLineCom = 1; + else + sb.append(ch); + } + else + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + { + lineReader.close(); + throw new IllegalArgumentException("Missing closing bracket in: " + line); + } + } + + sb.append(ch); + } + } + fromIndex = 0; + } + } + catch (IOException e) + { + e.printStackTrace(); + } + + LogProvider.instance.logErr("Variable " + varName + " was not found!"); + return null; + }*/ + + /** + * @param f | Source file. + * + * @return All lines from source file as string. + * @throws IOException + * + * @since 1.1.5 + */ + public static String LoadFileToString(File f) throws IOException + { + return LoadFileToString(f, 1); + } + + /** + * @param f | Source file. + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Content of file as string. + * @throws IOException + * + * @since 1.2.0 + */ + public static String LoadFileToString(File f, int endlMode) throws IOException + { + return StreamToString(new FileReader(f), endlMode); + } + + /** + * @param input | Input stream to read to string! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.5 + */ + public static String StreamToString(InputStream input, int endlMode) throws IOException + { + return StreamToString(new InputStreamReader(input), endlMode); + } + + /** + * @param input | Input reader! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.2 + */ + public static String StreamToString(Reader input, int endlMode) throws IOException + { + String l; + StringBuilder sb = new StringBuilder(); + + BufferedReader r = new BufferedReader(input); + while ((l = r.readLine()) != null) + { + sb.append(l); + if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) + sb.append("\n"); + } + r.close(); + return sb.toString(); + } + + /** + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.2.2 + */ + public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(null, cls, name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(obj, obj.getClass(), name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException + { + Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); + if (result != null) + return result; + result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); + if (result == null) + LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); + return result; + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param argClasses | Classes of args. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException + { + try + { + Method method = objCls.getMethod(name, argClasses); + Object resualt = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : resualt; + } + catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) + { + for (Method method : objCls.getMethods()) + if (method.getName().equals(name)) + try + { + Object resualt = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : resualt; + } + catch (IllegalArgumentException e) + {} + catch (SecurityException | IllegalAccessException ex) + { + ex.printStackTrace(); + } + } + return null; + } + + + //Syntactical analyzes and fast string utility: + + /** + * @param obj | Object to clone. + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.2.2 + */ + public static T Clone(T obj) + { + return Clone(obj, DataParser.REGISTRY, new Object[] {}, new Scope()); + } + + /** + * @param obj | Object to clone. + * @param + * @param converterArgs | Argument for {@link DataConverter#objToString(Registry, Object, Object...)}! + * @param parserArgs | Arguments for {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)}! + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Clone(T obj, Registry parsersToUse, Object[] converterArgs, Object... parserArgs) + { + if (obj == null) + return obj; + else if (obj.getClass() == Byte.class) + return (T) new Byte((byte) obj); + else if (obj.getClass() == Short.class) + return (T) new Short((short) obj); + else if (obj.getClass() == Integer.class) + return (T) new Integer((int) obj); + else if (obj.getClass() == Long.class) + return (T) new Long((long) obj); + else if (obj.getClass() == Float.class) + return (T) new Float((float) obj); + else if (obj.getClass() == Double.class) + return (T) new Double((double) obj); + else if (obj.getClass() == Character.class) + return (T) new Character((char) obj); + else if (obj.getClass() == Boolean.class) + return (T) new Boolean((boolean) obj); + else if (obj.getClass() == String.class) + return (T) new String((String) obj); + else + { + ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); + + Object cln = NULL.toOopNull(parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs)); + if (cln != null && cln != VOID) + return (T) cln; + + if (obj instanceof Cloneable) + { + try + { + Method method = Object.class.getDeclaredMethod("clone"); + method.setAccessible(true); + return (T) method.invoke(obj); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); + return obj; + } + } + + /** + * @param cls | Class to instantiate. + * + * @return New blank instance of required class created by calling shortest public constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.2.2 + */ + public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException + { + return Instantiate(cls, true); + } + + /** + * @param cls | Class to instantiate. + * @param publicOnly | If true, only public constructors will be used to create the object! + * + * @return New blank instance of required class created by calling shortest constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException + { + try + { + Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); + if (!publicOnly) + cons.setAccessible(true); + return cons.newInstance(); + } + catch (Exception e) + { + try + { + Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); + if (cnstrs.length <= 0) + throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); + + for (int i = 1; i < cnstrs.length; i++) + { + if (!publicOnly) + cnstrs[0].setAccessible(true); + if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) + cnstrs[0] = cnstrs[i]; + } + + Object[] args = new Object[cnstrs[0].getParameterCount()]; + Class[] argTypes = cnstrs[0].getParameterTypes(); + for (int i = 0; i < cnstrs[0].getParameterCount(); i++) + { + if (argTypes[i] == byte.class) + args[i] = (byte) 0; + else if (argTypes[i] == short.class) + args[i] = (short) 0; + else if (argTypes[i] == int.class) + args[i] = 0; + else if (argTypes[i] == long.class) + args[i] = 0l; + else if ( argTypes[i] == float.class) + args[i] = 0.0f; + else if (argTypes[i] == double.class) + args[i] = 0.0; + else if (argTypes[i] == char.class) + args[i] = (char) 0; + else if (argTypes[i] == boolean.class) + args[i] = false; + else if (argTypes[i] == String.class) + args[i] = ""; + else + args[i] = null; + } + return (T) cnstrs[0].newInstance(args); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) + { + e2.printStackTrace(); + } + } + return null; + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.2.2 + */ + public static Class[] ToClasses(Object... objs) + { + return ToClasses(true, objs); + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.3.5 + */ + public static Class[] ToClasses(boolean unwrapp, Object... objs) + { + Class[] classes = new Class[objs.length]; + if (unwrapp) + { + for (int i = 0; i < classes.length; i++) + { + if (objs[i] == null) + classes[i] = Object.class; + else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) + classes[i] = byte.class; + else if (objs[i].getClass() == Short.class || objs[i] == Short.class) + classes[i] = short.class; + else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) + classes[i] = int.class; + else if (objs[i].getClass() == Long.class || objs[i] == Long.class) + classes[i] = long.class; + else if (objs[i].getClass() == Float.class || objs[i] == Float.class) + classes[i] = float.class; + else if (objs[i].getClass() == Double.class || objs[i] == Double.class) + classes[i] = double.class; + else if (objs[i].getClass() == Character.class || objs[i] == Character.class) + classes[i] = char.class; + else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) + classes[i] = boolean.class; + else if (objs[i] instanceof Class) + classes[i] = (Class) objs[i]; + else + classes[i] = objs[i].getClass(); + } + + return classes; + } + + for (int i = 0; i < classes.length; i++) + classes[i] = objs[i].getClass(); + return classes; + } + + /** + * @param ch | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; + * + * @since 1.3.2 + */ + public static StringBuilder multilpy(char ch, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(ch); + return sb; + } + + /** + * @param ch | String to multiply! + * @param str | Count of multiplication! + * + * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; + * + * @since 1.3.0 + */ + public static StringBuilder multilpy(CharSequence str, int times) + { + StringBuilder sb = new StringBuilder(str); + while (times-- > 1) + sb.append(str); + return sb; + } + + /** + * @param s | String to split and check some syntax. + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.0.0 + */ + public static String[] splitValues(String s, char... splitter) + { + return splitValues(s, 0, true, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.3.0 + */ + public static String[] splitValues(String s, int limit, boolean splitAfterSingleCharOnly, char... splitter) + { + return splitValues(s, limit, splitAfterSingleCharOnly, new char[0], splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.3.5 + */ + public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) + { + if (splitter.length <= 0 || limit == 1) + return new String[] {s}; +// +// if (isOneOf(s.charAt(0), splitter)) +// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); + + List result = new ArrayList<>(); + + int brackets = 0, quote = 0, lastIndex = 0; + for (int i = 0, count = 1, len = s.length(), oldCh = splitter[0]; i < len && (limit <= 0 || count < limit); i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (isOneOf(ch, splitBreaks)) + { + brackets = quote = 0; + break; + } + + if (brackets == 0 && oldCh != ch && isOneOf(ch, splitter) && (oneOrMore || (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i).trim()); + count++; + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + s); + } + } + oldCh = ch; + } + + if (brackets > 0) + throw new IllegalArgumentException("Unclosed brackets in: " + s); + else if (quote % 2 != 0) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + else + { + result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, s.length()).trim()); + } + + return result.toArray(new String[0]); + } + + /** + * @param s | CharSequence to search! + * @param oneOf | Characters to find! + * + * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, char... oneOf) + { + return indexOfNotInObj(s, true, oneOf); + } + + /** + * @param s | CharSequence to search! + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param oneOf | Characters to find! + * + * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 + */ + public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... oneOf) + { + int found = -1; + for (int i = 0, brackets = 0, quote = 0, len = s.length(); i < len; i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) + { + found = i; + if (firstIndex) + return found; + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); + } + } + } + return found; + } + + /** + * @param s | CharSequence to search! + * @param sequenceToFind | CharSequence to find! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind) + { + return indexOfNotInObj(s, sequenceToFind, true); + } + + /** + * @param s | CharSequence to search! + * @param sequenceToFind | CharSequence to find! + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, boolean firstIndex) + { + int found = -1; + for (int i = 0, brackets = 0, quote = 0, match = 0, len = s.length(), lenToFind = sequenceToFind.length(); i < len; i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (brackets == 0 && ch == sequenceToFind.charAt(match++)) + { + if (match == lenToFind) + { + found = i - match + 1; + if (firstIndex) + return found; + match = 0; + } + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); + } + else + match = 0; + } + } + return found; + } + + /** + * @param str | String to do replacements in! + * @param target | Target to replace! + * @param replacement | Replacement for target! + * + * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! + * + * @since 1.2.0 + */ + public static String fastReplace(String str, String target, CharSequence replacement) + { + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, str.length()).toString(); + } + + /** + * @param ch | Char to compare! + * @param chars | Chars to match! + * + * @return True if inserted char is any of inserted chars! + * + * @since 1.3.0 + */ + public static boolean isOneOf(int ch, char... chars) + { + if (chars.length > 0) + { + for (int i = 0, len = chars.length; i < len; i++) + if (chars[i] == ch) + return true; + } + return false; + } + + /** + * @return {@link String#contains(CharSequence)} for char sequence! + * + * @since 1.3.0 + */ + public static boolean contains(CharSequence str, char... oneOf) + { + for (int i = 0, len = str.length(); i < len; i++) + if (isOneOf(str.charAt(i), oneOf)) + return true; + return false; + } + + /** + * @param str | String to display! + * @param pos | Position to display! + * + * @return String with displayed position! + * Use for debugging or error printing! + * + * @since 1.3.2 + */ + public static String showPosInString(CharSequence str, int pos) + { + return str + "\n" + multilpy(' ', pos) + "^"; + } + + /** + * @param obj | Object to map the serializer variables into! + * @param fromSerializer | Source serializer to map obj from! + * @param fieldNamesToUse | Array of obj field names to map/populate from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return Same obj after being populated/mapped by contents of fromSerializer via requested fields (fieldNamesToUse) and conversion rules listed below! + * Table of specific Serializer --> Object conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (obj) typeAction with obj
{@link File}{@link Serializer#SerializeTo(File)}
{@link Appendable}{@link Serializer#SerializeTo(Appendable)}
{@link OutputStream}{@link Serializer#SerializeTo(OutputStream)}
{@link URL}Serializer (fromSerializer) will open connection with {@link URL} and attempt serialize its content to it if possible!
{@link URLConnection}Serializer (fromSerializer) will attempt serialize its content into given {@link URLConnection} if possible!
{@link CharSequence} (as http address)Serializer (fromSerializer) will open connection with url and get + serialize the content into it if possible!
Others (default){@link Scope#into(Object, GenericScope, String...)} (return description)
+ + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during serialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static T into(Object obj, Serializer fromSerializer, String... fieldNamesToUse) throws Exception, IntrospectionException + { + if (obj instanceof File) + { + fromSerializer.SerializeTo((File) obj); + return (T) obj; + } + + if (obj instanceof Appendable) + { + fromSerializer.SerializeTo((Appendable) obj); + return (T) obj; + } + + if (obj instanceof OutputStream) + { + fromSerializer.SerializeTo((OutputStream) obj); + return (T) obj; + } + + if (obj instanceof URL) + { + URLConnection con = ((URL) obj).openConnection(); + con.setDoOutput(true); + if (con instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) con); + else + fromSerializer.SerializeTo(con.getOutputStream()); + return (T) con; + } + + if (obj instanceof URLConnection) + { + if (obj instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) obj); + else + fromSerializer.SerializeTo(((URLConnection) obj).getOutputStream()); + return (T) obj; + } + + try + { + if (obj instanceof CharSequence) + { + if (indexOfNotInObj((CharSequence) obj, "http") == 0) + { + URLConnection con = new URL(obj.toString()).openConnection(); + con.setDoOutput(true); + if (con instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) con); + else + fromSerializer.SerializeTo(con.getOutputStream()); + return (T) con; + } + + try + { + File file = new File(obj.toString()); + fromSerializer.SerializeTo(file); + return (T) file; + } + catch (Exception e) + {} + } + } + catch (IOException e) + {} + + return Scope.into(obj, fromSerializer, fieldNamesToUse); + } + + /** + * @param newInstance | New instance of specific {@link Serializer} + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link Serializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> Serializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#LoadFrom(CharSequence)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#LoadFrom(File)}
{@link Reader}{@link Serializer#LoadFrom(Reader)}
{@link InputStream}{@link Serializer#LoadFrom(InputStream)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + public static Serializer from(Serializer newInstance, Object fromObj, String... fieldNamesToUse) throws Exception, IntrospectionException + { + if (fromObj instanceof CharSequence) + { + if (indexOfNotInObj((CharSequence) fromObj, "http") == 0) + try + { + return newInstance.LoadFrom(new URL(fromObj.toString()).openStream()); + } + catch (IOException e) + {} + + try + { + return newInstance.LoadFrom(new File(fromObj.toString())); + } + catch (Exception e) + {} + + return newInstance.LoadFrom((CharSequence) fromObj); + } + + if (fromObj instanceof File) + return newInstance.LoadFrom((File) fromObj); + if (fromObj instanceof Reader) + return newInstance.LoadFrom((Reader) fromObj); + if (fromObj instanceof InputStream) + return newInstance.LoadFrom((InputStream) fromObj); + if (fromObj instanceof URL) + return newInstance.LoadFrom(((URL) fromObj).openStream()); + if (fromObj instanceof URLConnection) + return newInstance.LoadFrom(((URLConnection) fromObj).getInputStream()); + + newInstance.addAll(Scope.from(fromObj, fieldNamesToUse)); + return newInstance; + } + + /** + * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! + * + * @param serializer | Serializer to post. + * @param conn | Http connection to use! + * + * @throws IOException if posting failed! + * + * @since 1.3.5 + */ + public static void post(Serializer serializer, HttpURLConnection conn) throws IOException + { + StringBuilder postData = new StringBuilder(); + for (Map.Entry param : serializer.varEntrySet()) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); + } + + for (Object param : serializer) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); + } + + byte[] postDataBytes = postData.toString().getBytes("UTF-8"); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); + conn.setDoOutput(true); + conn.getOutputStream().write(postDataBytes); + } + + /** + * This is a "dummy" class that {@link Serializer} uses internally as an OOP programmatic interpretation of null. In otherwise this is wrapper object for null. + * Note: You should not be able to come in contact with this during serialization and loading, if you did then you most likely encountered and bug and you should report it! + * + * @author PETO + * + * @since 1.2.2 + */ + public static final class NULL + { + public static Object toOopNull(Object obj) + { + return obj == null ? new NULL() : obj; + } + + @Override + public boolean equals(Object obj) + { + return obj == null || obj instanceof NULL; + } + + @Override + public String toString() + { + return "null"; + } + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java new file mode 100644 index 0000000..ab77cc0 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java @@ -0,0 +1,199 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.ToClasses; +import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Serializer.splitValues; + +import java.lang.reflect.Array; +import java.util.Arrays; + +/** + * This converter is capable of converting primitive arrays. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + + + + + +
StringObject
1 2 3new int[] {1, 2, 3}
4 5 "hello!"new Object[] {4, 5, "hello!"}
"Lorem" "ipsum"new String[] {"Lorem", "ipsum"}
+ *
+ * This parser requires one optional parse method arg that is type of boolean at index 1 and it specifies if resolving datatype of a parsed array is required (default true). + * + * @author PETO + * + * @since 1.3.0 + */ +public class ArrayConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (indexOfNotInObj(str, ' ') > 0) + { + boolean findArrType = true; + if (args.length > 1 && args[1] instanceof Boolean) + findArrType = (boolean) args[1]; + + String[] strObjs = tokenize(str); + int len = strObjs.length; + Object[] objs = new Object[len]; + + Class arrClass = null; + for (int i = 0; i < len; i++) + { + Object obj = objs[i] = myHomeRegistry.parse(strObjs[i], args); + if (obj != null) + if (arrClass == null) + arrClass = obj.getClass(); + else if (arrClass != obj.getClass()) + arrClass = Object.class; + } + + if (findArrType && arrClass != null && !arrClass.equals(Object.class)) + try + { + return castArray(objs, arrClass); + } + catch (IllegalArgumentException e) + {} + return objs; + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj != null && myHomeRegistry != null && obj.getClass().isArray()) + { + int tabs = 0, index = 0; + if (args.length > 2 && args[2] instanceof Integer) + index = (int) args[2]; + + if (index <= 0 || myHomeRegistry.indexOf(OperationGroups.class) > -1) + { + if (args.length > 1 && args[1] instanceof Integer) + tabs = (int) args[1]; + + if (args.length > 2) + args[2] = index + 1; + + StringBuilder sb = new StringBuilder(); + for (int i = 0, length = Array.getLength(obj), sizeEndl = 10000; i < length; i++) + { + CharSequence str = myHomeRegistry.toString(Array.get(obj, i), args); + char ch = str.charAt(0); + if (ch == '{' || ch == '[') + sb.append("("+str+")"); + else + sb.append(str); + + if (i < length-1) + if (sb.length() > sizeEndl) + { + sb.append('\n'); + for (int j = 0; j < tabs+1; j++) + sb.append('\t'); + sizeEndl += 10000; + } + else + sb.append(' '); + } + return index > 0 ? sb.insert(0, '(').append(')') : sb; + } + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Primitive array " + objToDescribe + " converted by " + getClass().getName(); + } + + /** + * @param str | String to tokenize! + * + * @return String splitted according to defined rules! + * + * @since 1.3.2 + */ + public String[] tokenize(String str) + { + return splitValues(str, ' '); + } + + /** + * @param sourceArray | Array to cast! + * @param toType | Type to cast array in to! + * + * @return Array object casted in to required type! + * + * @since 1.3.2 + */ + public static Object castArray(Object[] sourceArray, Class toType) + { + int len = sourceArray.length; + Object arr = Array.newInstance(ToClasses(toType)[0], len); + for (int i = 0; i < len; i++) + Array.set(arr, i, sourceArray[i]); + return arr; + } + + /** + * @param arr1 | Object one that might be array! + * @param arr2 | Object two that might be array! + * + * @return New array consisting of array 1 and array 2! + * + * @throws IllegalArgumentException if object one is not an array! + * + * @since 1.3.2 + */ + public static Object[] mergeArrays(Object arr1, Object arr2) + { + Object[] array1 = fromAmbiguous(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguous(arr2) : new Object[] {arr2}; + Object[] result = Arrays.copyOf(array1, array1.length + array2.length); + System.arraycopy(array2, 0, result, array1.length, array2.length); + return result; + } + + /** + * @param array | Object that might be array! + * + * @return Object transformed in to primitive array! + * + * @throws IllegalArgumentException if the specified object is not an array! + * + * @since 1.3.2 + */ + public static Object[] fromAmbiguous(Object array) + { + int len1 = Array.getLength(array); + Object[] arr = new Object[len1]; + for (int i = 0; i < len1; i++) + arr[i] = Array.get(array, i); + return arr; + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java new file mode 100644 index 0000000..094c4be --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -0,0 +1,89 @@ +package org.ugp.serialx.converters; + +/** + * This converter is capable of converting {@link String}. + * Its case insensitive! + *
+ *
+ * Table of all string <--> object conversions: + + + + + + + + + + + + + + + + + + + + + + +
StringObject
truenew Boolean(true)
tnew Boolean(true)
falsenew Boolean(false)
fnew Boolean(false)
+ + * @author PETO + * + * @since 1.3.0 + */ +public class BooleanConverter implements DataConverter +{ + public boolean shorten; + + public BooleanConverter() + { + this(true); + } + + public BooleanConverter(boolean shorten) + { + setShorten(shorten); + } + + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (arg.equalsIgnoreCase("t") || arg.equalsIgnoreCase("true")) + return new Boolean(true); + else if (arg.equalsIgnoreCase("f") || arg.equalsIgnoreCase("false")) + return new Boolean(false); + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Boolean) + return isShorten() ? (boolean) obj ? "T" : "F" : (boolean) obj ? "true" : "false"; + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } + + public boolean isShorten() + { + return shorten; + } + + public void setShorten(boolean shorten) + { + this.shorten = shorten; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java new file mode 100644 index 0000000..90c775b --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -0,0 +1,69 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.fastReplace; + +/** + * This converter is capable of converting {@link Character}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
'a'new Character('a')
'35'new Character('#')
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class CharacterConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.length() > 1 && str.charAt(0) == '\'' && str.charAt(str.length()-1) == '\'') + try + { + if (str.equals("''")) + return new Character(' '); + else + return new Character((char) Integer.parseInt(str = fastReplace(str, "'", ""))); + } + catch (Exception e) + { + return new Character(str.charAt(0)); + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Character) + return "'"+(int) (char) obj+"'"; + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java new file mode 100644 index 0000000..c6fadf4 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -0,0 +1,103 @@ +package org.ugp.serialx.converters; + +import org.ugp.serialx.Registry; + +/** + * This is DataParser with extended functionality! {@link DataConverter} can also parse data like DataParser but is also capable of converting them back to string! + * This to string convertation is performed by {@link DataConverter#toString(Object)} and result of this convertation supposed to be parsable by {@link DataConverter#parse(String, Object...)} meaning one converter supposed to be parsing and converting via the same string format! + * + * @see DataParser + * + * @author PETO + * + * @since 1.3.0 + */ +public interface DataConverter extends DataParser +{ + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @since 1.3.0 + */ + CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args); + + /** + * @param myHomeRegistry | Registry of parsers (might be null)! + * @param objToDescribe | Object to generate description for! + * @param argsUsedConvert | Array of arguments that were used for converting described object! + * + * @return Description for object (should not contains endlines)! + * + * @since 1.3.0 + */ + default CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + this; + } + + /** + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Object converted to string using {@link DataConverter} suitable converter picked from {@link DataParser#REGISTRY}! + * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! + * + * @since 1.3.0 + */ + public static CharSequence objToString(Object obj, Object... args) + { + return REGISTRY.toString(obj, args); + } + + /** + * @deprecated Use {@link ParserRegistry#toString(Object, Object...)}! + * + * @param registry | Registry to use! + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Object converted to string using {@link DataConverter} suitable converter picked from registry! + * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! + * + * @since 1.3.0 + */ + @Deprecated + public static CharSequence objToString(Registry registry, Object obj, Object... args) + { + if (registry instanceof ParserRegistry) + return ((ParserRegistry) registry).toString(obj, args); + return objToString(new ParserRegistry(registry), obj, args); + } + + /** + * @deprecated Use {@link ParserRegistry#getConverterFor(Object, Object...)}! + * + * @param registry | Registry to use! + * @param obj | Object to find converter for! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Converter suitable for converting required obj to string, selected from registry! + */ + @Deprecated + public static DataConverter getConverterFor(Registry registry, Object obj, Object... args) + { + if (registry instanceof ParserRegistry) + return ((ParserRegistry) registry).getConverterFor(obj, args); + return getConverterFor(new ParserRegistry(registry), obj, args); + } + + /** + * @return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataParser.class.getName() + * + * @since 1.3.2 + */ + public static String getDefaultDescriptionFor(Object objToDescribe) + { + return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataConverter.class.getName(); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java new file mode 100644 index 0000000..37738bd --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -0,0 +1,427 @@ +package org.ugp.serialx.converters; + +import java.util.Collection; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Scope; +import org.ugp.serialx.converters.operators.NegationOperator; + +/** + * This class supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! + * Instance of DataParser should be registered into {@link DataParser#REGISTRY} or other external registry in order to work, also only one instance of each DataParser should be used and accessed via this registry!
+ * Static method {@link DataParser#parseObj} is used to walk this registry and parse inserted string in process, in other words we can say that this interface contains
recursive descent parse that uses its own implementations! + * + * @author PETO + * + * @since 1.3.0 + */ +public interface DataParser +{ + /** + * This is the way how {@link DataParser} represents void. You can return this in {@link DataParser#parse(String, Object...)} as a void. + * This can be useful when you are adding something to "storage" while parsing and you do not want it to be returned. + * + * @since 1.2.2 (moved to {@link DataParser} since 1.3.0) + * + * @see Void#TYPE + */ + public static final Object VOID = Void.TYPE; + + /** + * This is connected with {@link DataParser#parse(String, Object...)} and {@link DataParser#parseObj(String, Object...)}! And its a way to tell that this parser is not suitable for parsing obtained string and search for optimal one should continue. + * + * @since 1.3.0 + */ + public static final String CONTINUE = new String(); + + /** + * This is DataParser registry. Here your parser implementations should be registered in order to work properly! + * Only one parser should be usable for specific input string, otherwise order of registration is crucial! + * Defaultly there are parsers from ugp.org.SerialX.converters. + * + * @since 1.3.0 + */ + //TODO ParserRegistry + public static final ParserRegistry REGISTRY = new ParserRegistry(new OperationGroups(), new VariableConverter(), /*new ConditionalAssignmentOperators(), new ComparisonOperators(), new LogicalOperators(), new ArithmeticOperators(),*/ new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new NegationOperator(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param str | Source string! + * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! + * + * @return Object that was parsed from obtained string. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. + * + * @since 1.3.0 + */ + Object parse(ParserRegistry myHomeRegistry, String str, Object... args); + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate {@link DataParser#REGISTRY} and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! + * + * @since 1.3.0 + */ + public static Object parseObj(String str, Object... args) + { + return REGISTRY.parse(str, args); + } + + /** + * @deprecated Use {@link ParserRegistry#parse(String, Object...)}! + * + * @param registry | Registry to use! + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! + * + * @since 1.3.0 + */ + @Deprecated + public static Object parseObj(Registry registry, String str, Object... args) + { + return parseObj(registry, str, false, null, args); + } + + /** + * @deprecated Use {@link ParserRegistry#parse(String, boolean, Class[], Object...)}! + * + * @param registry | Registry to use! + * @param str | Source string to parse using suitable parser from registry. + * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message! + * @param ignore | {@link DataParser} class to ignore! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null or inserted string will be returned based on returnAsStringIfNotFound! + * + * @since 1.3.0 + */ + @Deprecated + public static Object parseObj(Registry registry, String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) + { + if (registry instanceof ParserRegistry) + return ((ParserRegistry) registry).parse(str, returnAsStringIfNotFound, ignore, args); + return parseObj(new ParserRegistry(registry), str, returnAsStringIfNotFound, ignore, args); + } + + /** + * @deprecated Use {@link DataParser.REGISTRY#getParserFor(String, Object...)}! + * + * @param registry | Registry to search! + * @param str | String to find parser for! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Parser suitable for parsing required string, selected from {@link DataParser#REGISTRY}! + * + * @since 1.3.0 + */ + @Deprecated + public static DataParser getParserFor(String str, Object... args) + { + return getParserFor(REGISTRY, str, args); + } + + /** + * @deprecated Use {@link DataParser#getParserFor(String, Object...)}! + * + * @param registry | Registry to search! + * @param str | String to find parser for! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Parser suitable for parsing required string, selected from inserted registry! + * + * @since 1.3.0 + */ + @Deprecated + public static DataParser getParserFor(Registry registry, String str, Object... args) + { + if (registry instanceof ParserRegistry) + return ((ParserRegistry) registry).getParserFor(str, args); + return getParserFor(new ParserRegistry(registry), str, args); + } + + /** + * Registry to store {@link DataParser} and {@link DataConverter} and performing parsing (String -> Object) and converting (Object -> String) operations with them! + * + * @author PETO + * + * @since 1.3.5 + */ + public static class ParserRegistry extends Registry + { + private static final long serialVersionUID = -2598324826689380752L; + + protected DataParser[] parsingCache; + protected DataParser[] convertingCache; + + /** + * Constructs an {@link ParserRegistry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public ParserRegistry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link ParserRegistry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public ParserRegistry(Collection c) + { + super(c); + } + + /** + * Constructs an {@link ParserRegistry} with parsers. + * + * @param parsers | Initial content of registry. + * + * @since 1.3.5 + */ + public ParserRegistry(DataParser... parsers) + { + super(parsers); + } + + @Override + public ParserRegistry clone() + { + return new ParserRegistry(this); + } + + /** + * @param str | String to find parser for! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Parser suitable for parsing required string, selected from inserted registry! + * + * @since 1.3.5 + */ + public DataParser getParserFor(String str, Object... args) + { + for (DataParser parser : this) + if (parser.parse(this, str, args) != CONTINUE) + return parser; + return null; + } + + /** + * @param obj | Object to find converter for! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Converter suitable for converting required obj to string, selected from registry! + * + * @since 1.3.5 + */ + public DataConverter getConverterFor(Object obj, Object... args) + { + for (DataParser parser : this) + if (parser instanceof DataConverter && ((DataConverter)parser).toString(this, obj, args) != CONTINUE) + return (DataConverter) parser; + return null; + } + + /** + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Object converted to string using {@link DataConverter} suitable converter picked from registry! + * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! + * + * @since 1.3.5 + */ + public CharSequence toString(Object obj, Object... args) + { + CharSequence str = null; + if (convertingCache != null) + for (DataParser parser : convertingCache) + if (parser != null && (str = ((DataConverter) parser).toString(this, obj, args)) != CONTINUE) + return str; + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(this, obj, args)) != CONTINUE) + { + if (convertingCache != null && i < convertingCache.length) + convertingCache[i] = parser; + return str; + } + } + + LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + return null; + } + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! + * + * @since 1.3.5 + */ + public Object parse(String str, Object... args) + { + return parse(str, false, null, args); + } + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message! + * @param ignore | {@link DataParser} class to ignore! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null or inserted string will be returned based on returnAsStringIfNotFound! + * + * @since 1.3.5 + */ + public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) + { + Object obj = null; + if (parsingCache != null) + for (DataParser parser : parsingCache) + if (parser != null && (obj = parser.parse(this, str, args)) != CONTINUE) + return obj; + + registryLoop: for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (ignore != null) + for (Class cls : ignore) + if (cls == parser.getClass()) + continue registryLoop; + + if ((obj = parser.parse(this, str, args)) != CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + return obj; + } + } + + if (returnAsStringIfNotFound) + return str; + + LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + return null; + } + + /** + * @param classOfParserToPrecache | Class of parser to precache! + * + * @return Int array of 2 signifying the index of where the parser was inserted in parsing cache and converting cache (index 0 = parsing cache index, index 1 = converting cache index) + */ + public int[] preCache(Class classOfParserToPrecache) + { + int[] ret = {-1, -1}; + if (parsingCache == null && convertingCache == null) + return ret; + + DataParser parser = null; + int i = 0; + for (int size = size(); i < size; i++) + { + DataParser elm = get(i); + Class objCls = elm.getClass(); + if (objCls == classOfParserToPrecache) + { + parser = elm; + break; + } + } + + if (parser == null) + return ret; + + if (i < parsingCache.length) + { + parsingCache[i] = parser; + ret[0] = i; + } + + if (i < convertingCache.length) + { + convertingCache[i] = parser; + ret[1] = i; + } + + return ret; + } + + /** + * Recreates and enables both parsing cache and converting cache! Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other!
+ * Note: Doing this will destroy any existing cache (this is usually not a big problem)! + * + * @see ParserRegistry#destroyCache() + * + * @since 1.3.5 + */ + public void resetCache() + { + int size = size(); + resetCache(new DataParser[size], new DataParser[size]); + } + + /** + * You can use this to manually set caching arrays. Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other! + * + * @param parsingCache | Array of specific parsing cache to use (it can contains some preached parsers to use preferably). This array is supposed to be as long as this registry! + * @param convertingCache | Array of specific converter cache to use (it can contains some preached converters to use preferably). This array is supposed to be as long as this registry! + * + * @since 1.3.5 + */ + public void resetCache(DataParser[] parsingCache, DataParser[] convertingCache) + { + if (parsingCache != null) + this.parsingCache = parsingCache; + if (convertingCache != null) + this.convertingCache = convertingCache; + } + + /** + * Destroys any existing cache and stops any further caching! Use this if you are experiencing some strange behaviors! + * + * @since 1.3.5 + */ + public void destroyCache() + { + this.parsingCache = this.convertingCache = null; + } + + /** + * @return Cache array for parsing (null if caching is disabled)! + * + * @since 1.3.5 + */ + public DataParser[] getParsingCache() + { + return parsingCache; + } + + /** + * @return Cache array for converting (null if caching is disabled)! + * + * @since 1.3.5 + */ + public DataParser[] getConverterCache() + { + return convertingCache; + } + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java new file mode 100644 index 0000000..ce04a67 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -0,0 +1,61 @@ +package org.ugp.serialx.converters; + +import org.ugp.serialx.Serializer.NULL; + +/** + * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. + * Its case insensitive! + *
+ *
+ * Table of all string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
nullnull (object)
voidDataParser.VOID
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class NullConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry registry, String str, Object... args) + { + if (str.equalsIgnoreCase("null")) + return null; + else if (str.equalsIgnoreCase("void")) + return VOID; + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj == null || obj instanceof NULL) + return "null"; + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return "Null, the nothing!"; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java new file mode 100644 index 0000000..9936c63 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -0,0 +1,205 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.contains; +import static org.ugp.serialx.Serializer.fastReplace; + +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.converters.operators.NegationOperator; + +/** + * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! + * Its case insensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StringObject
1337new Integer(1337)
1337Lnew Long(1337)
1337Snew Short(1337)
137Ynew Byte(137)
13.37new Double(13.37)
13.37Dnew Double(13.37)
13.37Fnew Float(13.37)
+ Table of sample string --> object conversions: + + + + + + + + + +
0xffnew Integer(255)
0b1111new Integer(15)
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class NumberConverter implements DataConverter +{ + /** + * {@link DecimalFormat} to format decimal numbers (double, float) during serialization!
+ * Default {@link DecimalFormat} will round decimal numbers to 3 decimal places (format pattern #.###)! + * + * Set this on null and decimal numbers will not be formated! Do this when you need accuracy! + * + * @serial 1.1.0 (moved to {@link NumberConverter} since 1.3.0) + */ + protected DecimalFormat decimalFormatter = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US)); + + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (arg.length() > 0) + { + char ch = arg.charAt(0); + if (ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9')) + { + arg = formatNum(arg.toLowerCase()); + if (arg.equals(".")) + return CONTINUE; + if (contains(arg, '.') || (!arg.startsWith("0x") && arg.endsWith("f") || arg.endsWith("d"))) + { + if (arg.endsWith("f")) + return new Float(fastReplace(arg, "f", "")); + else + return new Double(fastReplace(arg, "d", "")); + } + else + try + { + Number integer; + boolean isNeg = arg.charAt(0) == '-'; + if (isNeg) + arg = arg.substring(1); + if (arg.endsWith("l")) + integer = new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + else if (arg.endsWith("s")) + integer = new Short(Short.parseShort(fastReplace(fastReplace(fastReplace(arg, "s", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + else if (arg.endsWith("y")) + integer = new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10)); + else + integer = new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + return isNeg ? NegationOperator.negate(integer) : integer; + } + catch (NumberFormatException e) + { + if (arg.matches("[0-9.]+")) + try + { + return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + } + catch (NumberFormatException e2) + { + LogProvider.instance.logErr("Number " + arg + " is too big for its datatype! Try to change its datatype to double (suffix D)!", e2); + return null; + } + } + } + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Number) + { + String str = decimalFormatter != null ? decimalFormatter.format(obj) : obj.toString(); + if (!contains(str, '.') && obj instanceof Double) + str += "D"; + else if (obj instanceof Float) + str += "F"; + else if (obj instanceof Long) + str += "L"; + if (obj instanceof Short) + str += "S"; + else if (obj instanceof Byte) + str += "Y"; + return str; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } + + /** + * @return {@link DecimalFormat} to format decimal numbers (double, float) during serialization or null if there is none! + * Value of {@link NumberConverter#decimalFormatter} + * + * @since 1.3.7 + */ + public DecimalFormat getDecimalFormatter() { + return decimalFormatter; + } + + /** + * @param decimalFormatter | New {@link DecimalFormat} to set for formating decimal numbers (double, float)! + * + * @since 1.3.7 + */ + public void setDecimalFormatter(DecimalFormat decimalFormatter) { + this.decimalFormatter = decimalFormatter; + } + + /** + * @param num | Number string to format! + * + * @return Original string with formated sign and deleted '_'! + * + * @since 1.3.0 + */ + public static String formatNum(String num) + { + if (num.length() > 2) + for (boolean minus = num.startsWith("+-") || num.startsWith("-+"); minus || num.startsWith("++") || num.startsWith("--"); minus = num.startsWith("+-") || num.startsWith("-+")) + { + num = num.substring(2); + if (minus) + num = "-"+num; + } + + return fastReplace(num, "_", ""); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java new file mode 100644 index 0000000..59e55c8 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java @@ -0,0 +1,525 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.InvokeStaticFunc; +import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Serializer.isOneOf; +import static org.ugp.serialx.Serializer.splitValues; + +import java.io.IOException; +import java.io.Serializable; +import java.io.StringReader; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.JussSerializer; +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + +/** + * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! + * This is also responsible for {@link Scope}! + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + +
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
+
+ This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
+ This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
+ * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class ObjectConverter implements DataConverter +{ + /** + * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) + */ + protected boolean useBase64IfCan = false; + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) + { + Class objectClass = null, oldObjectClass; + boolean hasOp, hasCls = false; + char ch; + + if (str.length() > 0 && ((hasOp = (ch = str.charAt(0)) == '{' || ch == '[') && (hasCls = (ch = str.charAt(str.length()-1)) == '}' || ch == ']') /*|| containsNotInObj(str, ' ')*/ || (objectClass = getProtocolExprClass(str, compilerArgs)) != null)) + { + if (objectClass != null) + { + if (objectClass == IsSelectorScope.class) + { + StringBuilder sb = new StringBuilder(str); + sb.setCharAt(str.indexOf(' '), '='); + return myHomeRegistry.parse(sb.toString(), compilerArgs); + } + else + { + if (compilerArgs.length < 5) + compilerArgs = Arrays.copyOf(compilerArgs, 5); + oldObjectClass = (Class) compilerArgs[4]; + compilerArgs[4] = objectClass; + } + + String[] args = splitValues(str = str.trim(), ' '); + if (!isOneOf(args[0].charAt(0), '{', '[') && args[0].contains("::")) + { + String[] clsAttr = args[0].split("::"); + if (clsAttr.length > 1) + { + if (args.length > 1) + try + { + Object rtrn = InvokeStaticFunc(objectClass, clsAttr[1], parseAll(myHomeRegistry, args, 1, true, compilerArgs)); + compilerArgs[4] = oldObjectClass; + return rtrn; + } + catch (InvocationTargetException e) + { + LogProvider.instance.logErr("Exception while calling method \"" + clsAttr[1] + "\":", e); + e.printStackTrace(); + } + else + try + { + compilerArgs[4] = oldObjectClass; + return clsAttr[1].equals("class") ? objectClass : clsAttr[1].equals("new") ? Serializer.Instantiate(objectClass) : objectClass.getField(clsAttr[1]).get(null); + } + catch (NoSuchFieldException e) + { + try + { + Object rtrn = InvokeStaticFunc(objectClass, clsAttr[1], parseAll(myHomeRegistry, args, 1, true, compilerArgs)); + compilerArgs[4] = oldObjectClass; + return rtrn; + } + catch (InvocationTargetException e2) + { + LogProvider.instance.logErr("Exception while calling method \"" + clsAttr[1] + "\":", e2); + e.printStackTrace(); + } + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to obtain value of field \"" + clsAttr[1] + "\" in class \"" + objectClass.getSimpleName() + "\" because:", e); + e.printStackTrace(); + } + /*catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to invoke \"" + args[0].split("::")[1] + "\" because class \"" + args[0].split("::")[0] + "\" was not found!"); + } */ + } + } + else + { + try + { + if ((ch = str.charAt(str.length()-1)) == ';' || ch == ',') + throw new ClassNotFoundException(); + + Object[] objArgs = parseAll(myHomeRegistry, args, 1, true, compilerArgs); + if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objectClass)) + return objArgs[0]; + compilerArgs[4] = oldObjectClass; + return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, objectClass, objArgs); + + /*Object obj; + if (objArgs.length == 1 && objArgs[0] instanceof Scope) + { + Scope scope = (Scope) objArgs[0]; + if ((obj = p.unserialize(objectClass, scope.toValArray())) != null) + return obj; + return p.unserialize(objectClass, scope); + } + else + { + if ((obj = p.unserialize(objectClass, objArgs)) != null) + return obj; + return p.unserialize(objectClass, new Scope(objArgs)); + }*/ + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while unserializing instance of \"" + objectClass.getName() + "\":", e); + e.printStackTrace(); + } + } + compilerArgs[4] = oldObjectClass; + } + else + { + Serializer scope; + try + { + if (compilerArgs.length > 0 && compilerArgs[0] instanceof Serializer) + { + if (compilerArgs.length > 4 && compilerArgs[4] instanceof Class && Serializer.class.isAssignableFrom((Class) compilerArgs[4])) + scope = ((Serializer) compilerArgs[0]).emptyClone((Class) compilerArgs[4], (GenericScope) compilerArgs[0]); + else + scope = ((Serializer) compilerArgs[0]).emptyClone(); + } + else + scope = getPreferredSerializer(); + } + catch (Exception e) + { + scope = getPreferredSerializer(); + } + + if (indexOfNotInObj(str, '=', ':', ';', ',') > -1) + { + compilerArgs = compilerArgs.clone(); + compilerArgs[0] = false; + return ((Serializer) scope.inheritParent()).LoadFrom(new StringReader(str), compilerArgs); + } + + if (hasOp && hasCls) + { + str = str.substring(1, str.length()-1).trim(); + if (str.isEmpty()) + return scope; + + int index; + if ((index = indexOfNotInObj(str, '=', ';', ',')) > -1 && (index >= str.length()-1 || str.charAt(index+1) != ':') || (objectClass = getProtocolExprClass(str, compilerArgs)) == null || objectClass == IsSelectorScope.class) + { + compilerArgs = compilerArgs.clone(); + compilerArgs[0] = false; + return ((Serializer) scope.inheritParent()).LoadFrom(new StringReader(str), compilerArgs); + } + + if (objectClass != null && indexOfNotInObj(str, "::") > -1) + return myHomeRegistry.parse(str, compilerArgs); + return parse(myHomeRegistry, str, compilerArgs); + } + else if (str.split(" ").length > 1) + { + LogProvider.instance.logErr("Unable to unserialize \"" + str + "\"! Possible reason of this is absence of comma or semicolon, try to insert them into empty spaces!", null); + return null; + } + } + LogProvider.instance.logErr("Unable to unserialize \"" + str + "\" because there is no such class or source string is corrupted!", null); + return null; + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + return toString(myHomeRegistry, arg, null, args); + } + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param preferedProtocol | Protocol to use preferably. + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) + { + if (arg == null) + return CONTINUE; + + if (useBase64IfCan && arg instanceof Serializable) + return CONTINUE; + + if (arg instanceof Scope) + { + Serializer serializer; + try + { + if (arg instanceof Serializer) + serializer = (Serializer) arg; + else if (args.length > 0 && args[0] instanceof Serializer) + (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) arg); + else + serializer = getPreferredSerializer(); + } + catch (Exception e) + { + serializer = getPreferredSerializer(); + } + + if (serializer instanceof JussSerializer) + ((JussSerializer) serializer).setGenerateComments(args.length > 5 && args[5] instanceof Boolean && (boolean) args[5]); + + try + { + if (args.length < 4) + args = Arrays.copyOf(args, 4); + else + args = args.clone(); + args[2] = 0; + args[3] = serializer.getProtocols(); + + StringBuilder sb = new StringBuilder(); + GenericScope parent; + if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) + sb.append(serializer.getImports().getAliasFor(arg.getClass()) + " "); + return serializer.SerializeAsSubscope(sb, args); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + else + { + if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) + { + Object[] objArgs; + Class oldObjectClass = null; + try + { + int tabs = 0, index = 0; + if (args.length > 1 && args[1] instanceof Integer) + tabs = (int) args[1]; + + if (args.length > 2 && args[2] instanceof Integer) + index = (int) args[2]; + + if (args.length < 5) + args = Arrays.copyOf(args, 5); + oldObjectClass = (Class) args[4]; + args[4] = arg.getClass();; + + objArgs = preferedProtocol.serialize(arg); + StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, arg.getClass()) + (objArgs.length <= 0 ? "" : " ")); + + args = args.clone(); + for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) + { + if (args.length > 2) + args[2] = index + 1; + sb.append(myHomeRegistry.toString(objArgs[i], args)); + if (i < objArgs.length-1) + if (sb.length() > sizeEndl) + { + sb.append('\n'); + for (int j = 0; j < tabs+1; j++) + sb.append('\t'); + sizeEndl += 10000; + } + else + sb.append(' '); + } + + args[4] = oldObjectClass; + return index > 0 && objArgs.length > 0 ? sb.insert(0, '{').append('}') : sb; + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while serializing instance of \"" + arg.getClass().getName() + "\":", e); + e.printStackTrace(); + } + args[4] = oldObjectClass; + } + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + if (obj instanceof Scope && ((Scope) obj).isEmpty()) + return "Empty scope!"; + else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) + return "Multiline char sequence!"; + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); + } + + /** + * @return Serializer that is supposed to be used for serializing sub-scopes if there is no other option. + * + * @since 1.3.5 + */ + public Serializer getPreferredSerializer() + { + return new JussSerializer(); + } + + /** + * @return True if program is forced to use {@link Base64} serialization on {@link Serializable} objects. + * This might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public boolean isUseBase64IfCan() + { + return useBase64IfCan; + } + + /** + * @param useBase64IfCan | Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public void setUseBase64IfCan(boolean useBase64IfCan) + { + this.useBase64IfCan = useBase64IfCan; + } + + /** + * @param obj | Object to get protocol for! + * @param mode | Protocol mode! + * @param args | Parser args to get protocol from! + * + * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
+ * Note: This is mainly used by {@link ObjectConverter}! + * + * @since 1.3.5 + */ + public static SerializationProtocol getProtocolFor(Object obj, byte mode, Object[] args) + { + if (args.length > 3) + { + if (args[3] instanceof ProtocolRegistry) + return ((ProtocolRegistry) args[3]).GetProtocolFor(obj, mode); + else if (args[3] instanceof SerializationProtocol) + return (SerializationProtocol) args[3]; + } + + return SerializationProtocol.REGISTRY.GetProtocolFor(obj, mode); + } + + /** + * @param str | String to check protocol class for! + * + * @return Class of the protocol or null if inserted statement is not protocol expression! + * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! + * + * @since 1.3.0 + */ + public static Class getProtocolExprClass(String str, Object[] compilerArgs) + { + int i = 0, len = str.length(); + for (char ch; i < len; i++) + if ((ch = str.charAt(i)) == ' ' || ch == ':') + break; + + try + { + Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ObjectConverter.class.getClassLoader()); + if (cls != null) + return cls; + for (char ch; i < len; i++) + { + if ((ch = str.charAt(i)) > 32) + if (ch == '{' || ch == '[') + return IsSelectorScope.class; + else + return null; + } + } + catch (ClassNotFoundException e) + {} + return null; + } + + /** + * @param registry | Registry to use! + * @param strs | Source strings to parse using suitable parser from registry. + * @param from | Start index to begin from! + * @param trim | If true, all strings will be trimed before parsing! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Array of parsed objects, each parsed using {@link DataParser#parseObj(String, Object...)} + * + * @since 1.3.0 + */ + public static Object[] parseAll(ParserRegistry registry, String strs[], int from, boolean trim, Object... args) + { + Object[] objs = new Object[strs.length-from]; + for (int i = 0; from < strs.length; from++, i++) + objs[i] = registry.parse(trim ? strs[from].trim() : strs[from], args); + return objs; + } + + /** + * @return Array with 2 preferred sub-scope wrapping chars that are used during serialization by default. { and } + * + * @since 1.3.5 + */ + public static char[] primarySubscopeWrappers() + { + return new char[] {'{', '}'}; + } + + /** + * @return Array with 2 secondary sub-scope wrapping char. [ and ] + * + * @since 1.3.5 + */ + public static char[] secondarySubscopeWrappers() + { + return new char[] {'[', ']'}; + } + + /** + * Used internally by {@link ObjectConverter}!
+ * Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: + * + * shortenedSelectorLikeScope {

+ * //stuff... + * }; + *
+ * + * @author PETO + * + * @since 1.3.0 + */ + protected static class IsSelectorScope {}; +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java new file mode 100644 index 0000000..161f254 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java @@ -0,0 +1,185 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.isOneOf; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Serializer; + +/** + * This parser provides ability to use expression groups that can define order of expression evaluation and compilation! + * Its usage depends on combination with other parsers especially operators! + * Its case sensitive! + *
+ *
+ * For example: (5 + 5) / 2 = 5 which is different than 5 + 5 / 2 = 7 + *
+ * This protocol will insert one additional argument into array of additional parsing args at index 2 that will be of type {@link Map} and it will contains informations about encapsulated groups, do not alter this map in any way unless you know what are you doing! + * + * @author PETO + * + * @since 1.3.0 + */ +public class OperationGroups implements DataParser +{ + /** + * Opening and closing of group mark! + * + * @since 1.3.0 + */ + public static final String GROUP_MARK_OP = new String(new char[] {127, 128, 129}), GROUP_MARK_CLS = new String(new char[] {129, 128, 127}); + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.length() > 1) + { + int opIndex = indexOfOpening(str, 0, '('), clsIndex = -1; + if (opIndex > -1 && (clsIndex = indexOfClosing(str, opIndex, new char[] {'('}, ')')) > -1) + { + Map runtimeGroupStack = new HashMap<>(); + if (args.length > 2 && args[2] instanceof Map) + runtimeGroupStack = (Map) args[2]; + else + { + if (args.length < 3) + args = Arrays.copyOf(args, 3); + args[2] = runtimeGroupStack; + } + String mark = GROUP_MARK_OP + runtimeGroupStack.size() + GROUP_MARK_CLS; + runtimeGroupStack.put(mark, str.substring(opIndex+1, clsIndex)); + + StringBuilder sb = new StringBuilder(str).replace(opIndex, clsIndex+1, mark); + return myHomeRegistry.parse(sb.toString(), args); + } + + if (isGroupMark(str)) + { + if (args.length > 2 && args[2] instanceof Map) + { + Map runtimeGroupStack = (Map) args[2]; + + Object[] newArgs = args.clone(); + newArgs[2] = new HashMap(); + return myHomeRegistry.parse(runtimeGroupStack.get(str), newArgs); + } + LogProvider.instance.logErr("Runtime group stack is trying to be accessed using " + str + " however it was not provided yet!", null); + return null; + } + } + + return CONTINUE; + } + + /** + * @param s | Char sequence to check! + * + * @return Return true if inserted CharSequence match the runtime group mark wrapper! + * This is used for internal purposes of {@link OperationGroups}. + * + * @since 1.3.0 + */ + public static boolean isGroupMark(CharSequence s) + { + String op = GROUP_MARK_OP, cls = GROUP_MARK_CLS; + int lo = op.length(), lc = cls.length(), len = s.length(); + if (len < lo + lc + 1) + return false; + for (int i = 0; i < lo; i++) + if (s.charAt(i) != op.charAt(i)) + return false; + + for (int i = lo, ch; i < len - lc; i++) + if ((ch = s.charAt(i)) < '0' || ch > '9') + return false; + + for (int i = 0; i < lc; i++) + if (s.charAt(len-i-1) != cls.charAt(lc-i-1)) + return false; + return true; + } + + /** + * @param str | CharSequence to search! + * @param from | Beginning index of search! + * @param openings | Openings to find! + * + * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link Serializer#indexOfNotInObj(CharSequence, char...)}! + * + * @since 1.3.0 + */ + public static int indexOfOpening(CharSequence str, int from, char... openings) + { + for (int len = str.length(), quote = 0, brackets = 0; from < len; from++) + { + char ch = str.charAt(from); + + if (ch == '\"') + quote++; + else if (quote % 2 == 0) + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + str); + } + else if (brackets == 0 && isOneOf(ch, openings)) + return from; + } + } + return -1; + } + + /** + * @param str | CharSequence to search! + * @param from | Beginning index of search! + * @param openings | Openings to count with! + * @param closing | Closings to find! + * + * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link Serializer#indexOfNotInObj(CharSequence, char...)}! + * + * @since 1.3.0 + */ + public static int indexOfClosing(CharSequence str, int from, char[] openings, char... closing) + { + for (int len = str.length(), quote = 0, brackets = 0, ops = 0; from < len; from++) + { + char ch = str.charAt(from); + + if (ch == '\"') + quote++; + else if (quote % 2 == 0) + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + str); + } + else if (brackets == 0) + { + if (isOneOf(ch, openings)) + ops++; + else if (isOneOf(ch, closing)) + { + if (ops == 1) + return from; + ops--; + } + } + } + } + return -1; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java new file mode 100644 index 0000000..b2bb26a --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -0,0 +1,150 @@ +package org.ugp.serialx.converters; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Base64; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.protocols.SerializationProtocol; + +/** + * This converter is capable of converting {@link Serializable}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
#rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAAdwQAAAAAeA#3D#3Dnew ArrayList()
#rO0ABXVyAAJbSU26YCZ26rKlAgAAeHAAAAADAAAABQAAAAUAAAAFnew int[] {5, 5, 5}
+ * Note: In most of the cases {@link ObjectConverter} and {@link SerializationProtocol} should be used as preferable alternative!
+ * Note: In order to avoid conflicts with JUSS syntax, this converter serializes and deserializes by using {@link Base64} and {@link URLEncoder} with addition of all % are being replaced by #! + * + * @author PETO + * + * @since 1.3.0 + */ +public class SerializableBase64Converter implements DataConverter +{ + /** + * @deprecated DO NOT USE, IT WILL TAKE NOTE EFFECT! USE {@link ObjectConverter#setUseBase64IfCan(boolean)}! + * + * Set this on true to force program to use SerializationProtocol also on java.io.Serializable objects. + * Doing this also might take less memory space then using classic java.io.Serializable. + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization! + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) + */ + @Deprecated + public static boolean useProtocolIfCan = true; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (arg.length() <= 0) + return CONTINUE; + + char ch0 = arg.charAt(0); + if (ch0 == '#' || ch0 == 'r') + { + try + { + if (ch0 == '#') + return UnserializeClassis(arg = URLDecoder.decode(arg.substring(1).replace('#', '%'), "UTF-8")); + return UnserializeClassis(arg = URLDecoder.decode(arg.replace('#', '%'), "UTF-8")); + } + catch (Exception e) + { + LogProvider.instance.logErr("Looks like there appear some problems with unserializing some object, the instance of java.io.Serializable from string \"" + arg + "\"! This string is most likely corrupted! See error below:", e); + e.printStackTrace(); + return null; + } + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + if (arg instanceof Serializable) + try + { + return "#" + URLEncoder.encode(SerializeClassic((Serializable) arg), "UTF-8").replace('%', '#'); + } + catch (Exception e) + { + LogProvider.instance.logErr("Looks like there appear some problems with serializing \"" + arg + "\", the instance of java.io.Serializable. This could happen when certain object contains non-transient unserializable objects. Use custom valid protocol for serializing \"" + arg + "\" might solve the problem!", e); + e.printStackTrace(); + return null; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj).append("\" serialized using classic Base64 java.io.Serializable!"); + } + + /** + * @param objStr | String to unserialize by classic Java serialization. + * + * @return Unsrialized object. + * + * @throws IOException - if an I/O error occurs while reading stream header. + * @throws ClassNotFoundException - Class of a serialized object cannot be found. + * + * @see java.util.Base64 + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) + */ + public static Object UnserializeClassis(String objStr) throws Exception + { + return new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(objStr))).readObject(); + } + + /** + * @param obj | Object to serialize using classic Java serialization. + * + * @return String with serialized object. + * + * @throws Exception - if an I/O error occurs while writing stream header + * + * @see java.lang.Base64 + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) + */ + public static String SerializeClassic(Serializable obj) throws Exception + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + + oos.writeObject(obj); + oos.close(); + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java new file mode 100644 index 0000000..206dd48 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -0,0 +1,101 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.contains; +import static org.ugp.serialx.Serializer.indexOfNotInObj; + +import org.ugp.serialx.Registry; + +/** + * This converter is capable of converting {@link String}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + +
StringObject
"Hello world!"new String("Hello world!")
+ * If you enter string in ${yourString}, "yourString" will be returned by {@link StringConverter#toString(Registry, Object, Object...)} according to {@link StringConverter#CodeInsertion(String)}! + * + * @author PETO + * + * @since 1.3.0 + */ +public class StringConverter implements DataConverter +{ + /** + * Set this on true and {@link String} will be serialized normally, for instance "Hello world!" and not using protocols or java Base64!
+ * Setting this on false will also make Strings unreadable for normal people! + * + * @since 1.2.0 (moved to {@link StringConverter} since 1.3.0) + */ + public static boolean serializeStringNormally = true; + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + if (arg instanceof String) + { + String str = arg.toString(); + if (str.startsWith("${") && str.endsWith("}")) + { + str = str.substring(2, str.length()-1); + if (str.contains("::") && indexOfNotInObj(str, ' ') > -1) + str = "{"+str+"}"; + return str; + } + else if (serializeStringNormally) + { + if (contains(str, '\"', '\n', '\r')) + return CONTINUE; + else + return "\""+str+"\""; + } + } + return CONTINUE; + } + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.length() > 1 && str.charAt(0) == '\"' && str.charAt(str.length()-1) == '\"' && indexOfNotInObj(str, ' ') == -1) + return str.substring(1, str.length() - 1); + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + String str = obj.toString(); + boolean hasComment = false; + if (str.startsWith("${") && str.endsWith("}") && !(hasComment = str.substring(2).contains("//"))) + return "Manually inserted code!"; + if (!hasComment) + return new StringBuilder().append("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\"!"); + return ""; + } + + /** + * @param obj | Object to stringify directly. + * + * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString(Registry, Object, Object...))}, it will be returned without ${ and }! + * + * @since 1.3.5 + */ + public static String DirectCode(Object obj) + { + return "${" + obj + "}"; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java new file mode 100644 index 0000000..6937c7b --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java @@ -0,0 +1,222 @@ +package org.ugp.serialx.converters; + +import static org.ugp.serialx.Serializer.Clone; +import static org.ugp.serialx.Serializer.contains; +import static org.ugp.serialx.Serializer.fastReplace; +import static org.ugp.serialx.Serializer.multilpy; +import static org.ugp.serialx.Serializer.splitValues; + +import java.util.AbstractMap; +import java.util.Arrays; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer.NULL; + +/** + * This converter is capable of converting {@link Map.Entry} and reading variables from {@link Scope} via "$"! + * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... argument! + * Its case insensitive!
+ * Exact outputs of this converter are based on inserted scope! + * + * @author PETO + * + * @since 1.3.0 + */ +public class VariableConverter implements DataConverter +{ + protected boolean jsonStyle; + + public VariableConverter() + { + this(false); + } + + /** + * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! + * + * @since 1.3.2 + */ + public VariableConverter(boolean jsonStyle) + { + setJsonStyle(jsonStyle); + } + + /** + * Raw example of empty variable entry this converter can convert! + * + * @since 1.3.0 + */ + public static final Entry RAW_VAR_ENTRY = NewVariable("", "null"); + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) + { + GenericScope scope = (GenericScope) args[0]; + boolean genericVar = args.length > 4 && args[4] == GenericScope.class; + if (isVarAssignment(arg)) + { + String[] enrty = splitValues(arg, 0, false, new char[] {'?'}, '=', ':'); + + Object obj = null; + String objString = enrty[enrty.length-1]; + + if (enrty.length > 1 && !objString.isEmpty()) + { + obj = NULL.toOopNull(myHomeRegistry.parse(objString, args)); + } + + for (int i = 0; i < enrty.length-1; i++) + { + if (!genericVar && contains(enrty[i] = enrty[i].trim(), ' ')) + LogProvider.instance.logErr("Variable name \"" + enrty[i] + "\" is invalid, blank characters are not allowed!", null); + else + { + if ((enrty[i] = fastReplace(enrty[i], "$", "")).indexOf('.') > -1) + { + String[] tree = splitValues(enrty[i], '.'); + GenericScope sc = (GenericScope) scope.getGenericScope((Object[]) Arrays.copyOfRange(tree, 0, tree.length-1)); + if (sc != null) + { + if (obj == VOID) + sc.variables().remove(enrty[i]); + else + sc.put(genericVar ? myHomeRegistry.parse(tree[tree.length-1], true, null, args) : tree[tree.length-1], obj); + } + else + LogProvider.instance.logErr("Variable \"" + tree[tree.length-2] +"\" was not declared as scope in its scope so variable \"" + tree[tree.length-1] +"\" cant be set to \"" + obj + "\"!", null); + } + else if (obj == VOID) + scope.variables().remove(enrty[i]); + else + scope.put(genericVar ? myHomeRegistry.parse(enrty[i], true, null, args) : enrty[i], obj); + } + } + if (arg.charAt(0) == '$') + return obj; + return VOID; + } + else if (arg.charAt(0) == '$' && !contains(arg, ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) + { + Object obj; + if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1) + { + Object[] tree = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.'); + GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(tree, 0, tree.length-1)); + obj = sc == null ? null : sc.variables().get(tree[tree.length-1]); + /*if (sc == null || !sc.containsVariable(tree[tree.length-1])) + LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/ + } + else + { + String str = fastReplace(fastReplace(arg, "::new", ""), "::class", ""); + /*if (!scope.containsVariable(str)) + LogProvider.instance.logErr("Variable \"" + str + "\" was not declared! Defaulting to null!");*/ + obj = scope.variables().get(str); + } + + return arg.endsWith("::class") ? obj.getClass() : arg.endsWith("::new") ? Clone(obj) : obj; + } + } + return CONTINUE; + } + + @SuppressWarnings("unchecked") + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Entry) + { + Entry var = (Entry) obj; + int tabs = 0; + if (args.length > 1 && args[1] instanceof Integer) + tabs = (int) args[1]; + + boolean jsonStyle = isJsonStyle(), genericVar = false; + Object key = (genericVar = !((key = var.getKey()) instanceof String)) ? myHomeRegistry.toString(key, args) : key, val = var.getValue(); + return new StringBuilder().append(jsonStyle && !genericVar ? "\""+key+"\"" : key).append(val instanceof Scope && !((Scope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")).append(myHomeRegistry.toString(val, args)); + } + return CONTINUE; + } + + @SuppressWarnings("unchecked") + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + Entry ent = (Entry) objToDescribe; + return new StringBuilder(myHomeRegistry.getConverterFor(ent.getValue(), argsUsedConvert).getDescription(myHomeRegistry, ent.getValue(), argsUsedConvert)).append(" Stored by \"").append(ent.getKey()).append("\" variable!"); + } + + /** + * @return True if variables will be serialized using json style ("key" : value)! + * + * @since 1.3.2 + */ + public boolean isJsonStyle() + { + return jsonStyle; + } + + /** + * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! + * + * @since 1.3.2 + */ + public void setJsonStyle(boolean jsonStyle) + { + this.jsonStyle = jsonStyle; + } + + /** + * @param s | CharSequence to search! + * + * @return true if inserted expression is variable assignment expression such as variable = 4 otherwise false! + * + * @since 1.3.0 + */ + public static boolean isVarAssignment(CharSequence s) + { + for (int i = 0, brackets = 0, quote = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (ch == '?') + return false; + else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) + return true; + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + if (brackets > 0) + brackets--; + } + oldCh = ch; + } + return false; + } + + /** + * @param varName | Name of variable. + * @param varValue | Value of variable. + * + * @return New entry with varName as name and varValue as value! + * + * @param | Generic type of variables value. + * + * @since 1.3.5 + */ + public static Entry NewVariable(String varName, T varValue) + { + return new AbstractMap.SimpleImmutableEntry<>(varName, varValue); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java new file mode 100644 index 0000000..66755ad --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -0,0 +1,129 @@ +package org.ugp.serialx.converters.imports; + +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.imports.ImportConverter.Imports; + +/** + * This class is represents single import. It stores target class of import and its alias!
+ * This imports are stored and managed in {@link Imports} and are used by many parsers and {@link Serializer}! + * + * @author PETO + * + * @since 1.3.0 + * + * @see Import + */ +public class Import implements Cloneable +{ + protected final Class cls; + protected final String alias; + protected final ImportsProvider owner; + + /** + * @param cls | Class to create import for! Alias of this class will be its simple name! + * + * @since 1.3.0 + */ + public Import(Class cls) + { + this(cls, cls.getSimpleName()); + } + + /** + * @param cls | Class to create import for! Alias of this class will be its simple name! + * @param owner | Owner/provider of this Import! + * + * @since 1.3.5 + */ + public Import(Class cls, ImportsProvider owner) + { + this(cls, cls.getSimpleName(), owner); + } + + /** + * @param cls | Class to create import for! + * @param alias | Alias of class! + * + * @since 1.3.5 + */ + public Import(Class cls, String alias) + { + this(cls, alias, null); + } + + + /** + * @param cls | Class to create import for! + * @param alias | Alias of class! + * @param owner | Owner/provider of this Import! + * + * @since 1.3.5 + */ + public Import(Class cls, String alias, ImportsProvider owner) + { + this.cls = cls; + this.alias = alias; + this.owner = owner; + } + + @Override + public String toString() + { + if (getCls().getSimpleName().equals(getClsAlias())) + return "import " + getCls().getName(); + return getCls().getName() + " => " + getClsAlias(); + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof String) + return getClsAlias().equals(obj); + else if (obj instanceof Class) + return getCls().equals(obj); + else if (obj instanceof Import) + return getClsAlias().equals(((Import) obj).getClsAlias()) && getCls().equals(((Import) obj).getCls()); + return super.equals(obj); + } + + @Override + public Import clone() + { + return new Import(getCls(), getClsAlias(), getOwner()); + } + + public Import clone(ImportsProvider newOwner) + { + return new Import(getCls(), getClsAlias(), newOwner); + } + + /** + * @return Class of this import! + * + * @since 1.3.0 + */ + public Class getCls() + { + return cls; + } + + /** + * @return Alias for class! + * + * @since 1.3.0 + */ + public String getClsAlias() + { + return alias; + } + + /** + * @return Owner/provider of this import! + * + * @since 1.3.5 + */ + public ImportsProvider getOwner() + { + return owner; + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java new file mode 100644 index 0000000..92f8524 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java @@ -0,0 +1,267 @@ +package org.ugp.serialx.converters.imports; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; + +/** + * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! + * Parsing example: import java.util.ArrayList will add temporary {@link Import} of java.util.ArrayList or java.lang.String => Word will import java.lang.String as Word! + * Imports will be converted to string just by calling toString!
+ *
+ * This parser requires additional parser arg at index 0 of type {@link ImportsProvider} that will obtain managed imports! This arg is required during both parsing and converting! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ImportConverter implements DataConverter +{ + /** + * List of global shared common registered imports! + * + * @since 1.3.0 + */ + public static final Imports IMPORTS = new Imports(new Import(Serializer.class), new Import(Scope.class), new Import(ArrayList.class), new Import(Math.class), new Import(Double.class), new Import(Integer.class), new Import(Double.class, "double"), new Import(Integer.class, "int"), new Import(String.class), new Import(System.class)); + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (args.length > 0 && args[0] instanceof ImportsProvider) + { + Imports imports = ((ImportsProvider) args[0]).getImports(); + int index; + if (str.startsWith("import ")) + { + try + { + if ((str = str.substring(7).trim()).indexOf("=>") > -1) + return parse(myHomeRegistry, str, args); + imports.add(new Import(imports.forName(str), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str + " because there is no such a class!", e); + } + return VOID; + } + else if ((index = (str = str.trim()).indexOf("=>")) > -1) + { + try + { + imports.add(new Import(imports.forName(str.substring(0, index).trim()), str.substring(index+2).trim(), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str.substring(0, index).trim() + " because there is no such a class!", e); + } + return VOID; + } + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) + { + return obj.toString(); + } + return CONTINUE; + } + + @Override + public String getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Import of " + ((Import) objToDescribe).getCls() + " as " + ((Import) objToDescribe).getClsAlias(); + } + + /** + * Collection used to store and operate with {@link Import}! + * + * @author PETO + * + * @since 1.3.5 + * + * @see ImportsProvider + */ + public static class Imports extends ArrayList implements Cloneable, ImportsProvider + { + private static final long serialVersionUID = 8487976264622823940L; + + /** + * Constructs an {@link Imports} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public Imports(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link Imports} with inserted imports c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Collection c) + { + super(c); + } + + /** + * Constructs an {@link Imports} with inserted imports. + * + * @param parsers | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Import... imports) + { + addAll(imports); + } + + @Override + public Imports clone() + { + return new Imports(this); + } + + @Override + public Imports getImports() + { + return this; + } + + /** + * @param imports | Imports to add. + * + * @return {@link ArrayList#addAll(Collection)}; + * + * @since 1.3.5 + */ + public boolean addAll(Import... imports) + { + return super.addAll(Arrays.asList(imports)); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName) throws ClassNotFoundException + { + return forName(aliasOrName, true, Imports.class.getClassLoader()); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. + * @param loader | Class loader from which the class must be loaded. + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * If there are no dots in required alias and alias is not imported then null will be returned! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException + { + Class cls = getClassFor(aliasOrName); + if (cls != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + return Class.forName(aliasOrName, initialize, loader); + /*try + { + return Class.forName("java.lang."+aliasOrName, initialize, loader); + } + catch (Exception e) + { + return null; + }*/ + return null; + } + + /** + * @param cls | Class to get alias for! + * + * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! + * + * @since 1.3.5 + */ + public String getAliasFor(Class cls) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(cls)) + return imp.getClsAlias(); + } + return cls.getName(); + } + + /** + * @param alias | Alias of class to obtain! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! + * + * @since 1.3.5 + */ + public Class getClassFor(String alias) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(alias)) + return imp.getCls(); + } + return null; + } + + /** + * @param owner | Owner of imports to get! + * + * @return Imports of provided owner stored by this list! + * + * @since 1.3.5 + */ + public Imports importsOf(ImportsProvider owner) + { + Imports imports = new Imports(); + for (Import imp : imports) + if (imp.getOwner() == owner) + imports.add(imp); + return imports; + } + + /** + * @param owner | Owner of imports to remove from this list! + * + * @since 1.3.5 + */ + public void removeImportsOf(ImportsProvider owner) + { + for (int i = size() - 1; i >= 0; i--) + if (get(i).getOwner() == owner) + remove(i); + } + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java new file mode 100644 index 0000000..5afa8a4 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -0,0 +1,130 @@ +package org.ugp.serialx.converters.imports; + +import java.util.Collection; + +import org.ugp.serialx.converters.imports.ImportConverter.Imports; + +/** + * This interface is supposed to be implemented by class that can provide array of imports! + * + * @author PETO + * + * @since 1.3.5 + */ +public interface ImportsProvider +{ + /** + * @return Array of provided imports! + * + * @since 1.3.5 + */ + public Imports getImports(); + + /** + * @param obj | Object to get imports from (its supposed to be instance of {@link ImportsProvider} or collection of {@link Import})! + * + * @return Imports of object or null if object can't provide any! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static Imports importsOf(Object obj) + { + if (obj == null) + return null; + + if (obj instanceof ImportsProvider) + return ((ImportsProvider) obj).getImports(); + + try + { + return new Imports((Collection) obj); + } + catch (Exception e) + { + return null; + } + } + + /** + * @param importProvider | Object to get imports from! + * @param aliasOrName | Alias of class or its full name! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class forName(Object importProvider, String aliasOrName) throws ClassNotFoundException + { + return forName(importProvider, aliasOrName, true, Imports.class.getClassLoader()); + } + + /** + * @param importProvider | Object to get imports from! + * @param aliasOrName | Alias of class or its full name! + * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. + * @param loader | Class loader from which the class must be loaded. + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * If there are no dots in required alias and alias is not imported then null will be returned! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class forName(Object importProvider, String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException + { + Class cls = getClassFor(importProvider, aliasOrName); + if (cls != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + return Class.forName(aliasOrName, initialize, loader); + /*try + { + return Class.forName("java.lang."+aliasOrName, initialize, loader); + } + catch (Exception e) + { + return null; + }*/ + return null; + } + + /** + * @param importProvider | Object to get imports from! + * @param cls | Class to get alias for! + * + * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static String getAliasFor(Object importProvider, Class cls) + { + Imports imports = importsOf(importProvider); + return imports != null ? imports.getAliasFor(cls) : cls.getName(); + } + + /** + * @param importProvider | Object to get imports from! + * @param alias | Alias of class to obtain! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class getClassFor(Object importProvider, String alias) + { + Imports imports = importsOf(importProvider); + return imports != null ? imports.getClassFor(alias) : null; + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java new file mode 100644 index 0000000..f1d1466 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -0,0 +1,495 @@ +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.Serializer.fastReplace; +import static org.ugp.serialx.Serializer.isOneOf; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.ArrayConverter; +import org.ugp.serialx.converters.DataParser; + +/** + * This parser provides arithmetics operators to evaluate mathematical expressions such as 5 * 2 +-- 2 / 2 ** 2 % 4 = 10! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ArithmeticOperators implements DataParser +{ + protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"}; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) + { + if (s.length() > 2 && isExpression(s, '+', '-', '*', '/', '%')) + return eval(myHomeRegistry, s, args); + return CONTINUE; + } + + /** + * @return Result of evaluated expression that was inserted! For instance 5 + 5, result 10! + * + * @since 1.3.0 + */ + protected Object eval(ParserRegistry registryForParsers, String expr, Object... argsForParsers) + { + while (expr.contains("++") || expr.contains("--") || expr.contains("+-") || expr.contains("-+")) + expr = fastReplace(fastReplace(fastReplace(fastReplace(expr, "-+", "-"), "+-", "-"), "--", "+"), "++", "+"); + + List[] terms = getTerms(expr, '+', '-', '*', '/', '%'); + List cofs = terms[0]; + if (cofs.size() <= 1) + return CONTINUE; + List oprs = terms[1]; + + Object cof1 = null, cof2 = null; + String opr = null; + try + { + for (int i = 0, index = -1, orderIndex = 0, size = oprs.size(); i < size; index = -1, i++) + { + for (String adept : priority1Oprs) + if ((orderIndex = oprs.indexOf(adept)) > -1 && (index == -1 || orderIndex < index)) + index = orderIndex; + for (String adept : priority2Oprs) + if ((orderIndex = oprs.indexOf(adept)) > -1) + index = orderIndex; + + cof1 = cofs.get(index = index < 0 ? 0 : index); + if (cof1 instanceof String) + cof1 = registryForParsers.parse(cof1.toString().trim(), i > 0, new Class[] {getClass(), ArrayConverter.class}, argsForParsers); + cof1 = cof1 instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1; + + cof2 = cofs.remove(index + 1); + if (cof2 instanceof String) + cof2 = registryForParsers.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers); + cof2 = cof2 instanceof ResultWrapper ? ((ResultWrapper) cof2).obj : cof2; + + opr = oprs.remove(index).toString(); + if (opr.charAt(0) == '+') + cofs.set(index, new ResultWrapper(addOperator(cof1, cof2))); + else if (opr.charAt(0) == '-') + cofs.set(index, new ResultWrapper(subOperator(cof1, cof2))); + else if (opr.startsWith("**")) + cofs.set(index, new ResultWrapper(powOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1))); + else if (opr.charAt(0) == '*') + cofs.set(index, new ResultWrapper(multOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1))); + else if (opr.charAt(0) == '/') + cofs.set(index, new ResultWrapper(divOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1))); + else if (opr.charAt(0) == '%') + cofs.set(index, new ResultWrapper(modOperator(cof1, cof2))); + } + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Arithmetic operator " + opr + " is undefined between " + cof1.getClass().getName() + " and " + cof2.getClass().getName() + "!", ex); + } + catch (IndexOutOfBoundsException ex) + { + LogProvider.instance.logErr("Missing coefficient in \"" + expr + "\"!", ex); + } + catch (ArithmeticException ex) + { + LogProvider.instance.logErr(ex.getMessage(), ex); + } + + return (cof1 = cofs.get(0)) instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1; + } + + /** + * @return Addition of cof and cof2 (cof + cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object addOperator(Object cof, Object cof2) + { + return add(toNum(cof), cof instanceof String ? cof2 : toNum(cof2)); + } + + /** + * @return Subtraction of cof and cof2 (cof - cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object subOperator(Object cof, Object cof2) + { + return sub(toNum(cof), toNum(cof2)); + } + + /** + * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign) supposed to be returned! + * + * @since 1.3.2 + */ + public Object multOperator(Object cof, Object cof2, int sign) + { + return mult(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign) supposed to be returned! + * + * @since 1.3.2 + */ + public Object divOperator(Object cof, Object cof2, int sign) + { + return div(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Modulation of cod and cof2 (cof % cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object modOperator(Object cof, Object cof2) + { + return mod(toNum(cof), toNum(cof2)); + } + + /** + * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign)) supposed to be returned! + * + * @since 1.3.2 + */ + public Object powOperator(Object cof, Object cof2, int sign) + { + return pow(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Addition of cof and cof2 (cof + cof2)! + * + * @since 1.3.0 + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object add(Object cof, Object cof2) + { + if (cof instanceof Number && cof2 instanceof Number) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() + ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() + ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() + ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); + } + + if (cof.getClass().isArray()) + return ArrayConverter.mergeArrays(cof, cof2); + + if (cof instanceof Collection) + { + if (cof2 instanceof Collection) + ((Collection) cof).addAll(((Collection) cof2)); + else if (cof2.getClass().isArray()) + ((Collection) cof).addAll(Arrays.asList(ArrayConverter.fromAmbiguous(cof2))); + else + ((Collection) cof).add(cof2); + return cof; + } + + if (cof instanceof Scope) + { + if (cof2 instanceof Scope) + ((Scope) cof).addAll(((Scope) cof2)); + else if (cof2 instanceof Collection) + ((Scope) cof).addAll((Collection) cof2); + else if (cof2.getClass().isArray()) + ((Scope) cof).addAll(ArrayConverter.fromAmbiguous(cof2)); + else + ((Scope) cof).add(cof2); + return cof; + } + return String.valueOf(cof) + String.valueOf(cof2); + } + + /** + * @return Subtraction of cof and cof2 (cof - cof2)! + * + * @since 1.3.0 + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object sub(Object cof, Object cof2) + { + if (cof instanceof Number && cof2 instanceof Number) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() - ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() - ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() - ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); + } + + if (cof instanceof Collection) + { + if (cof2 instanceof Collection) + ((Collection) cof).removeAll(((Collection) cof2)); + else if (cof2.getClass().isArray()) + ((Collection) cof).removeAll(Arrays.asList(ArrayConverter.fromAmbiguous(cof2))); + else + ((Collection) cof).remove(cof2); + return cof; + } + + return null; + } + + /** + * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign)! + * + * @since 1.3.0 + */ + public static Object mult(Object cof, Object cof2, int sign) + { + if (cof2 instanceof Number) + { + if (!(cof instanceof Number)) + return Serializer.multilpy(cof.toString(), ((Number) cof2).intValue() * sign).toString(); + + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() * ((Number) cof2).floatValue() * sign; + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() * ((Number) cof2).intValue() * sign; + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() * ((Number) cof2).longValue() * sign; + + return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; + } + + return Serializer.multilpy(cof2.toString(), ((Number) cof).intValue() * sign).toString(); + } + + /** + * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign)! + * + * @since 1.3.0 + */ + public static Object div(Object cof, Object cof2, int sign) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() / ((Number) cof2).floatValue() * sign; + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() / ((Number) cof2).intValue() * sign; + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() / ((Number) cof2).longValue() * sign; + + return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; + } + + /** + * @return Modulation of cod and cof2 (cof % cof2)! + * + * @since 1.3.0 + */ + public static Object mod(Object cof, Object cof2) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() % ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() % ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() % ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); + } + + /** + * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign))! + * + * @since 1.3.0 + */ + public static Object pow(Object cof, Object cof2, int sign) + { + if (cof instanceof Number && cof2 instanceof Number) + { + double pow = Math.pow(((Number) cof).doubleValue(), ((Number) cof2).doubleValue() * sign); + if (pow > Long.MAX_VALUE || pow < Long.MIN_VALUE || cof instanceof Double || cof2 instanceof Double) + return pow; + else if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Float || cof2 instanceof Float)) + return (float) pow; + + if (pow > Integer.MAX_VALUE || pow < Integer.MIN_VALUE || cof instanceof Long || cof2 instanceof Long) + return (long) pow; + else if (cof instanceof Integer || cof2 instanceof Integer) + return (int) pow; + } + return null; + } + + /** + * + * @param str | String to split! + * @param operatos | If true, list of spited operators will be returned otherwise terms split after each operator. + * @param oprs | Operators to use as a splitters. + * + * @return List of terms splitted according to inserted arguments! For example getTerm("5 + 6", true, '+') will return [+], while getTerm("5 + 6", false, '+') will return [5, 6]! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public static List[] getTerms(String str, char... oprs) + { + List[] ret = new ArrayList[] {new ArrayList<>(), new ArrayList<>()}; //cofs, ops + + StringBuilder[] sbs = {new StringBuilder(), new StringBuilder()}; //cofs, ops + + int i = 0, type = 0, len = str.length(); + for (; i < len; i++) //in case of start cof sign + { + char ch = str.charAt(i); + if (isOneOf(ch, oprs)) + sbs[0].append(ch); + else + break; + } + + for (int quote = 0, brackets = 0, lastType = type; i < len; i++) + { + char ch = str.charAt(i); + if (ch == '\"') + quote++; + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + brackets--; + + if (type == 1 || quote % 2 == 0 && brackets == 0) + { + if ((type = isOneOf(ch, oprs) ? 1 : 0) != lastType) + { + String s = sbs[lastType].toString().trim(); + if (!s.isEmpty()) + ret[lastType].add(s); + sbs[lastType] = new StringBuilder(); + } + else + type = lastType; + } + + sbs[lastType = type].append(ch); + } + + if (sbs[type].length() > 0) + { + String s = sbs[type].toString().trim(); + if (!s.isEmpty()) + ret[type].add(s); + } + return ret; + } + + /** + * @param str | String that might be an expression! + * @param operators | Operators that str must have! + * + * @return True if inserted string is expression with any coefficients splitted by operators! + * + * @since 1.3.2 + */ + public static boolean isExpression(CharSequence str, char... operators) + { + int hasOpr = -1; + for (int i = 0, len = str.length(), oldCh = 0, isCof = 0, quote = 0, brackets = 0; i < len; i++) + { + char ch = str.charAt(i); + if (ch > 32) + { + if (ch == '\"') + quote++; + else if (quote % 2 == 0) + { + if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + brackets--; + else if (brackets == 0) + { + if (Serializer.isOneOf(ch, operators)) + hasOpr = isCof = 0; + else if (oldCh <= 32 && isCof == 1) + return false; + else + isCof = 1; + } + } + } + oldCh = ch; + } + return hasOpr == 0; + } + + /** + * @return null -> 0, bool ? 1 : 0 + * + * @since 1.3.0 + */ + public static Object toNum(Object obj) + { + if (obj == null) + return 0; + else if (obj instanceof Boolean) + return (boolean) obj ? 1 : 0; + else if (obj instanceof Character) + return (int) (char) obj; + return obj; + } + + /** + * DEPRECATED: Use {@link String#valueOf(Object)} instead, this function is duplicate functionality rendering it unnecessary. + * + * @return "null" if null and else obj.toString(); + * + * @since 1.3.0 + */ + @Deprecated + public static String toString(Object obj) + { + return obj == null ? "null" : obj.toString(); + } + + /** + * Used internally by {@link ArithmeticOperators} to wrap result of evaluation! + * Mainly used by String results! + * + * @author PETO + * + * @since 1.3.0 + */ + protected static class ResultWrapper + { + public final Object obj; + + public ResultWrapper(Object obj) + { + this.obj = obj; + } + + @Override + public String toString() + { + return obj.toString(); + } + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java new file mode 100644 index 0000000..44b593d --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -0,0 +1,184 @@ +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.Serializer.indexOfNotInObj; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Scope; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.imports.ImportsProvider; + +/** + * This parser provides comparison operators to compare 2 objects! For example 6 > 5 or 5 == 5 returns true! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ComparisonOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int index = -1; + if (str.length() > 2 && (indexOfNotInObj(str, '>', '<', '!', '=') > -1 || (index = indexOfNotInObj(str, " instanceof ")) > -1)) + { + if (index > -1) + { + try + { + return ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(index+12).trim()).isInstance(myHomeRegistry.parse(str.substring(0, index).trim(), args)); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to check if object " + str.substring(0, index).trim() + " is instance of class \"" + str.substring(index+12).trim() + "\" because there is no such a class!", e); + return null; + } + } + else if ((index = str.indexOf("!=")) > -1) + { + boolean isTripple = str.charAt(index+2) == '='; + return !equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + } + else if ((index = str.indexOf("==")) > -1) + { + boolean isTripple = str.charAt(index+2) == '='; + return equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + } + else if ((index = str.indexOf('<')) > -1) + { + boolean orEqual = str.charAt(index+1) == '='; + return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), false, orEqual); + } + else if ((index = str.indexOf('>')) > -1) + { + boolean orEqual = str.charAt(index+1) == '='; + return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), true, orEqual); + } + //System.out.println(str); + } + //double t = System.nanoTime(); + //System.out.println((t-t0)/1000000); + return CONTINUE; + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * @param compareInstances | If true, this method will compare objects using == operator! + * + * @return True supposed to be returned if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.2 + */ + public boolean equalsOperator(Object obj1, Object obj2, boolean compareInstances) + { + return equals(obj1, obj2, compareInstances); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2 to be compared with Object 1! + * @param isGreater | If true, Object 1 must be greater than Object 2 in order for true to be returned! + * @param orEqual | If true, Object 1 being numerically equal to Object 2 will result in true to be returned! + * + * @return True supposed to be returned according to arguments! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public Object comparisonOperator(Object obj1, Object obj2, boolean isGreater, boolean orEqual) + { + try + { + return numberComparator(((Number) (obj1 = toCompareFriendly(obj1))).doubleValue(), ((Number) (obj2 = toCompareFriendly(obj2))).doubleValue(), isGreater, orEqual); + } + catch (ClassCastException ex) + { + if (obj1 instanceof Comparable) + return numberComparator(((Comparable) obj1).compareTo(obj2), 0, isGreater, orEqual); + + LogProvider.instance.logErr("Comparison operator is undefined between " + obj1.getClass().getName() + " and " + obj2.getClass().getName() + "!", ex); + return null; + } + } + + /** + * @return {@link Map} -> {@link Map#size()}, {@link Collection} -> {@link Collection#size()}, {@link CharSequence} -> {@link CharSequence#length()}, array -> array.length otherwise {@link ArithmeticOperators#toNum(Object)} + * + * @since 1.3.0 + */ + public static Object toCompareFriendly(Object obj) + { + if (obj instanceof Map) + return ((Map) obj).size(); + else if (obj instanceof Collection) + return ((Collection) obj).size(); + else if (obj instanceof Scope) + return ((Scope) obj).valuesCount() + ((Scope) obj).variablesCount(); + else if (obj instanceof CharSequence) + return ((CharSequence) obj).length(); + else if ((obj = ArithmeticOperators.toNum(obj)).getClass().isArray()) + return Array.getLength(obj); + return obj; + } + + /** + * @param d1 | Number 1! + * @param d2 | Number 2 to be compared with number 1! + * @param isGreater | If true, number 1 must be greater than number 2 in order for true to be returned! + * @param orEqual | If true, number 1 being equal to number 2 will result in true to be returned! + * + * @return True according to arguments! + * + * @since 1.3.2 + */ + public static boolean numberComparator(double d1, double d2, boolean isGreater, boolean orEqual) + { + return isGreater ? (orEqual ? d1 >= d2 : d1 > d2) : (orEqual ? d1 <= d2 : d1 < d2); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.0 + */ + public static boolean equals(Object obj1, Object obj2) + { + return equals(obj1, obj2, false); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * @param compareInstances | If true, this method will compare objects using == operator! + * + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.2 + */ + public static boolean equals(Object obj1, Object obj2, boolean compareInstances) + { + return compareInstances ? obj1 == obj2 || obj1 != null && obj2 != null && obj1.getClass() == obj2.getClass() && numericallyEquals(obj1, obj2) : Objects.deepEquals(obj1, obj2) || numericallyEquals(obj1, obj2); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * + * @return True if obj1 numerically equals to obj2! For instance true == 1, null == 0! + * + * @since 1.3.2 + */ + public static boolean numericallyEquals(Object obj1, Object obj2) + { + return (obj1 = ArithmeticOperators.toNum(obj1)) instanceof Number && (obj2 = ArithmeticOperators.toNum(obj2)) instanceof Number && ((Number) obj1).doubleValue() == ((Number) obj2).doubleValue(); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java new file mode 100644 index 0000000..ffeee37 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -0,0 +1,123 @@ +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.Serializer.indexOfNotInObj; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Serializer.NULL; +import org.ugp.serialx.converters.DataParser; + +/** + * This parser provides conditional assignment operators more specially ternary and null coalescing! For example true ? "Yes" : "No" will return "Yes" and null ?? "Hello!" will return hello! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ConditionalAssignmentOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.length() > 2 && indexOfNotInObj(str, '?') > -1) + { + int index = indexOfOne(str, 0, '?'); + if (index > -1) + { + try + { + String last = str.substring(index+1), first = str.substring(0, index); + boolean condition = (boolean) LogicalOperators.toBool(myHomeRegistry.parse(first.trim(), args)); + if ((index = indexOfTernaryElse(last, 1, '?', ':')) > -1) + { + first = last.substring(0, index); + return condition ? myHomeRegistry.parse(first.trim(), args) : (last = last.substring(index+1).trim()).isEmpty() ? VOID : myHomeRegistry.parse(last, args); + } + else + return condition ? myHomeRegistry.parse(last.trim(), args) : VOID; + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr(str.substring(0, index).trim() + " is invalid condition for ternary operator! Condition must be boolean, try to insert \"!= null\" check!", ex); + return null; + } + } + + if ((index = str.indexOf("??")) > -1) + { + Object obj = myHomeRegistry.parse(str.substring(0, index).trim(), args); + if (obj != null && !(obj instanceof NULL)) + return obj; + + String next = str.substring(index+2); + if ((next = next.trim()).isEmpty()) + return null; + return myHomeRegistry.parse(next, args); + } + } + return CONTINUE; + } + + /** + * @param str + * @param defaultCountOfConfitions + * @param tenraryTokens + * + * @return + * + * @since 1.3.5 + */ + public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) + { + for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, quote = 0, brackets = 0; i < len; i++) + { + char ch = str.charAt(i); + if (ch == '\"') + quote++; + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + brackets--; + else if (quote % 2 == 0 && brackets == 0) + { + for (char token : ternaryOperators) + if (ch == token && oldCh != token && (i >= len-1 || str.charAt(i+1) != token)) + { + defaultCountOfConfitions += token == ternaryOperators[0] ? 1 : -1; + tokenCount++; + } + + if (defaultCountOfConfitions == 0 && tokenCount > 0) + return i; + } + oldCh = ch; + } + return -1; + } + + /** + * @param str + * @param from + * @param oneChar + * + * @return + * + * @since 1.3.5 + */ + public static int indexOfOne(CharSequence str, int from, char oneChar) + { + for (int len = str.length(), oldCh = -1, quote = 0, brackets = 0; from < len; from++) + { + char ch = str.charAt(from); + if (ch == '\"') + quote++; + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + brackets--; + else if (quote % 2 == 0 && brackets == 0 && ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) + return from; + oldCh = ch; + } + return -1; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java new file mode 100644 index 0000000..a0f8487 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -0,0 +1,152 @@ +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.converters.operators.ArithmeticOperators.getTerms; + +import java.util.List; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.converters.DataParser; + +/** + * This parser provides logical operators to evaluate boolean expressions such as false || true && true ^ false = true! + * + * @author PETO + * + * @since 1.3.0 + */ +public class LogicalOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) + { + if (s.length() > 2 && indexOfNotInObj(s, '&', '|', '^') > -1) + { + List[] terms = getTerms(s, '&', '|', '^'); + List cofs = terms[0]; + if (cofs.size() <= 1) + return CONTINUE; + + List oprs = terms[1]; + + Object cof1 = null, cof2 = null, opr = null; + try + { + for (int i = 0, index = 0, size = oprs.size(); i < size; index = 0, i++) + { + opr = oprs.remove(index); + if (opr.equals("&&")) + { + cof1 = cofs.get(index); + if (cof1 instanceof String) + cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); + if (cof1.equals(false)) + { + cofs.remove(index + 1); + cofs.set(index, false); + } + else + { + cof2 = cofs.remove(index + 1); + if (cof2 instanceof String) + cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); + cofs.set(index, andOperator(cof1, cof2)); + } + } + else if (opr.equals("||")) + { + cof1 = cofs.get(index); + if (cof1 instanceof String) + cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); + if (cof1.equals(true)) + { + return true; + } + else + { + cof2 = cofs.remove(index + 1); + if (cof2 instanceof String) + cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); + cofs.set(index, orOperator(cof1, cof2)); + } + } + else if (opr.equals("^")) + { + cof1 = cofs.get(index); + if (cof1 instanceof String) + cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); + + cof2 = cofs.remove(index + 1); + if (cof2 instanceof String) + cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); + cofs.set(index, xorOperator(cof1, cof2)); + } + } + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Logical operator " + opr + " is undefined between " + cof1.getClass().getName() + " and " + cof2.getClass().getName() + "!", ex); + } + catch (IndexOutOfBoundsException e) + { + LogProvider.instance.logErr("Missing coefficient in \"" + s + "\"!", e); + } + return cofs.get(0); + } + return CONTINUE; + } + + /** + * @return True if obj1 and obj2 is true! + * + * @since 1.3.2 + */ + public Object andOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) && (boolean) toBool(obj2); + } + + /** + * @return True if obj1 or obj2 is true! + * + * @since 1.3.2 + */ + public Object orOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) || (boolean) toBool(obj2); + } + + /** + * @return True if obj1 xor obj2 is true! + * + * @since 1.3.2 + */ + public Object xorOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) ^ (boolean) toBool(obj2); + } + + /** + * @return null -> false or if number > 0 + * + * @since 1.3.0 + */ + public static Object toBool(Object obj) + { + if (obj == null) + return false; + else if (obj instanceof Number) + return ((Number) obj).doubleValue() > 0; + else if (obj instanceof Character) + return (char) obj > 0; + /*else if (obj instanceof Map) + return !((Map) obj).isEmpty(); + else if (obj instanceof Collection) + return !((Collection) obj).isEmpty(); + else if (obj instanceof Scope) + return !((Scope) obj).isEmpty(); + else if (obj.getClass().isArray()) + return Array.getLength(obj) > 0;*/ + return obj; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java new file mode 100644 index 0000000..d59f941 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -0,0 +1,81 @@ +package org.ugp.serialx.converters.operators; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.converters.DataParser; + +/** + * This parser provides ability to negate stuff! For example !true returns false! + * + * @author PETO + * + * @since 1.3.0 + */ +public class NegationOperator implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int ch, len = str.length(); + if (len > 0 && ((ch = str.charAt(0)) == '-' || ch == '!')) + { + int negCount = 1; + for (int i = negCount; i < len; i++) + if ((ch = str.charAt(i)) == '-' || ch == '!') + negCount++; + else + break; + + Object obj = myHomeRegistry.parse(str.substring(negCount), args); + if (negCount % 2 == 0) + return obj; + Object neg = notOperator(obj); + if (obj == neg && !(obj instanceof Number && ((Number) obj).intValue() == 0)) + LogProvider.instance.logErr("Unable to nagete \"" + obj + "\" because object of \"" + obj.getClass().getName() + "\" cant be negated!", null); + return neg; + } + return CONTINUE; + } + + + /** + * @param obj | Object to negate! + * + * @return Negated object supposed to be returned or same object as argument if object can't be negated! Only numbers and booleans can be negated! + * + * @since 1.3.2 + */ + public Object notOperator(Object obj) + { + return negate(obj); + } + + /** + * @param obj | Object to negate! + * + * @return Negated object or same object as argument if object can't be negated! Only numbers and booleans can be negated! + * + * @since 1.3.0 + */ + public static Object negate(Object obj) + { + if (obj == null) + return 0; + else if (obj instanceof Boolean) + obj = !((boolean) obj); + else if (obj.getClass() == Byte.class) + obj = (byte) -((Number) obj).byteValue(); + else if (obj.getClass() == Short.class) + obj = (short) -((Number) obj).shortValue(); + else if (obj.getClass() == Integer.class) + obj = -((int) obj); + else if (obj.getClass() == Character.class) + obj = (char) -((Character) obj); + else if (obj.getClass() == Long.class) + obj = -((long) obj); + else if (obj.getClass() == Float.class) + obj = -((float) obj); + else if (obj.getClass() == Double.class) + obj = -((double) obj); + return obj; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java new file mode 100644 index 0000000..2246d6d --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java @@ -0,0 +1,235 @@ +package org.ugp.serialx.protocols; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; + +/** + * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! + * This protocol is applicable on anything you want however condition of use is absence of final field otherwise {@link AutoProtocol#createBlankInstance(Class)} should be overridden. ALso you should {@link AutoProtocol#createBlankInstance(Class)} when you object is to complex! + * + * @author PETO + * + * @param | Generic type of object to use protocol for. + * + * @since 1.2.2 + */ +public class AutoProtocol extends SerializationProtocol +{ + static { + UNIVERSAL_INTROSPECTION = new ArrayList<>(); + } + + /** + * Universal instance of AutoProtocol that is applicable for any {@link Object}! + * + * @since 1.3.5 + * + * @see AutoProtocol#UNIVERSAL_SCOPE + */ + public static final AutoProtocol UNIVERSAL = new AutoProtocol<>(Object.class, AutoProtocol.UNIVERSAL_INTROSPECTION); + + /** + * Universal instance of AutoProtocol that is applicable for any {@link Object}! + * Object will be serialized as {@link Scope}! + * + * @since 1.3.5 + */ + public static final AutoProtocol UNIVERSAL_SCOPE = new AutoProtocol<>(Object.class, true, AutoProtocol.UNIVERSAL_INTROSPECTION); + + /** + * This is information for {@link AutoProtocol} to always introspect structure of every object before that is being serialized or deserialized, which means all fields with public and valid getters and setters will be serialized for every object! + *
+ * This is default behavior of {@link AutoProtocol} when no fields are specified in constructor! + * + * @since 1.3.5 + */ + public static final List UNIVERSAL_INTROSPECTION; + + protected final Class applicableFor; + protected List fieldDescriptors = new ArrayList<>(); + protected HashMap, List> cache = new HashMap<>(); + protected boolean useScope; + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param fieldsToSerialize | Names of fields to serialize, if empty array is put there then all fields with public and valid getters and setters will be serialized! + * + * @throws IntrospectionException when there are no field with valid and public getters and setters. + * + * @since 1.2.2 + */ + public AutoProtocol(Class applicableFor, String... fieldsToSerialize) throws IntrospectionException + { + this(applicableFor, false, fieldsToSerialize); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null all fields width valid and public getters and setters will be serialized! + * + * @since 1.3.5 + */ + public AutoProtocol(Class applicableFor, List fieldsToSerialize) + { + this(applicableFor, false, fieldsToSerialize); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * @param fieldsToSerialize | Names of fields to serialize, if this array is empty or null then all fields with public and valid getters and setters will be serialized! + * + * @throws IntrospectionException when there are no fields with valid and public getters and setters. + * + * @since 1.3.2 + */ + public AutoProtocol(Class applicableFor, boolean useScope, String... fieldsToSerialize) throws IntrospectionException + { + this(applicableFor, useScope, fieldsToSerialize.length == 0 ? UNIVERSAL_INTROSPECTION : Scope.getPropertyDescriptorsOf(applicableFor, fieldsToSerialize)); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null {@link AutoProtocol#UNIVERSAL_INTROSPECTION} will take place! + * + * @since 1.3.5 + */ + public AutoProtocol(Class applicableFor, boolean useScope, List fieldsToSerialize) + { + this.applicableFor = applicableFor; + setUseScope(useScope); + this.fieldDescriptors = fieldsToSerialize == null ? UNIVERSAL_INTROSPECTION : fieldsToSerialize; + + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + try + { + Scope.getPropertyDescriptorsOf(applicableFor, cache); + } + catch (IntrospectionException e) + {} + } + + /** + * @param objectClass | Class to create new instance of! + * + * @return New blank instance of required class! When not override, it returns {@link Serializer#Instantiate(objectClass)} + * + * @throws Exception if any exception occurs (based on implementation). + * + * @since 1.2.2 + */ + public T createBlankInstance(Class objectClass) throws Exception + { + return Serializer.Instantiate(objectClass); + } + + @Override + public Object[] serialize(T object) throws Exception + { + List fieldDescriptors = this.fieldDescriptors; + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + fieldDescriptors = Scope.getPropertyDescriptorsOf(object.getClass(), cache); + + if (isUseScope()) + { + return new Object[] {Scope.from(object, fieldDescriptors)}; + } + else + { + int size = fieldDescriptors.size(); + Object[] args = new Object[size]; + for (int i = 0; i < size; i++) + args[i] = fieldDescriptors.get(i).getReadMethod().invoke(object); + return args; + } + } + + @Override + public T unserialize(Class objectClass, Object... args) throws Exception + { + List fieldDescriptors = this.fieldDescriptors; + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + fieldDescriptors = Scope.getPropertyDescriptorsOf(objectClass, cache); + + T obj = createBlankInstance(objectClass); + if (isUseScope() && args.length == 1 && args[0] instanceof Scope) + { + return Scope.into(obj, (Scope) args[0], fieldDescriptors); + } + + for (int i = 0, size = fieldDescriptors.size(); i < size && i < args.length; i++) + fieldDescriptors.get(i).getWriteMethod().invoke(obj, args[i]); + return obj; + } + + /** + * @deprecated DO NOT USE! + * + * @param variableName | Name of variable! + * + * @return PropertyDescriptor of variable with name or null if this protocols can't use it! + * + * @since 1.3.2 + */ + @Deprecated + public PropertyDescriptor getfieldDescriptorsDescriptor(String variableName) + { + for (PropertyDescriptor var : fieldDescriptors) + if (var.getName().equals(variableName)) + return var; + return null; + } + + @Override + public Class applicableFor() + { + return applicableFor; + } + + /** + * @return If true, objects will be serialized using scope which is longer but more readable! + * + * @since 1.3.2 + */ + public boolean isUseScope() + { + return useScope; + } + + /** + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * + * @since 1.3.2 + */ + public void setUseScope(boolean useScope) + { + this.useScope = useScope; + } + + /** + * DEPRECATED: DO NOT USE! USE {@link Scope#getPropertyDescriptorsOf(Class, String...)} instead! + * + * @param cls | Class to inspect! + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! + * + * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! + * + * @throws IntrospectionException when there are no fields with valid and public getters and setters. + * + * @see PropertyDescriptor + * + * @since 1.3.2 + */ + @Deprecated + public static List getPropertyDescriptorsOf(Class cls, String... fieldNames) throws IntrospectionException + { + return Scope.getPropertyDescriptorsOf(cls, fieldNames); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java new file mode 100644 index 0000000..f0bba4d --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java @@ -0,0 +1,33 @@ + package org.ugp.serialx.protocols; + +import java.util.Collection; + +/** + * EnumProtocol is universal protocol to serialize any enumerator ({@link Collection} instance). + * + * @author PETO + * + * @since 1.2.2 + */ +public class EnumProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Enum object) + { + return new Object[] {object.name()}; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Enum unserialize(Class> objectClass, Object... args) + { + return Enum.valueOf((Class) objectClass, args[0].toString()); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Enum.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java new file mode 100644 index 0000000..d2d99a8 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java @@ -0,0 +1,44 @@ +package org.ugp.serialx.protocols; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +/** + * ListProtocol is universal protocol to serialize any {@link Collection} instance. The condition of use is public constructor with one {@link Collection} argument. + * + * @author PETO + * + * @since 1.0.0 and applicable for {@link Collection} since 1.2.2 + */ +public class ListProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Collection obj) + { + return obj.toArray(); + } + + @Override + public Collection unserialize(Class> objectClass, Object... args) throws Exception + { + if (objectClass.isInterface()) + return new ArrayList<>(Arrays.asList(args)); + + try + { + return objectClass.getConstructor(Collection.class).newInstance(Arrays.asList(args)); + } + catch (Exception e) + { + return objectClass.getConstructor(Object[].class).newInstance(args); + } + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Collection.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java new file mode 100644 index 0000000..47af7e3 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java @@ -0,0 +1,50 @@ +package org.ugp.serialx.protocols; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.LogProvider; + +public class MapProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Map object) + { + Object[] args = new Object[object.size()*2]; + int i = 0; + for (Entry entry: object.entrySet()) + { + args[i] = entry.getKey(); + args[i+1] = entry.getValue(); + i+=2; + } + return args; + } + + @SuppressWarnings("unchecked") + @Override + public Map unserialize(Class> objectClass, Object... args) throws Exception + { + boolean isFromScope = args.length == 1 && args[0] instanceof GenericScope; + if (args.length % 2 != 0 && !isFromScope) + LogProvider.instance.logErr(getClass().getSimpleName() + ": Some variables have no values, this is not good!", null); + + if (objectClass.isInterface()) + objectClass = (Class>) HashMap.class; + + if (isFromScope) + return objectClass.getConstructor(Map.class).newInstance(((GenericScope) args[0]).variables()); + + return objectClass.getConstructor(Map.class).newInstance(GenericScope.mapKvArray(new LinkedHashMap<>(args.length/2), args)); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Map.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java new file mode 100644 index 0000000..d1c8a69 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java @@ -0,0 +1,47 @@ +package org.ugp.serialx.protocols; + +import java.util.HashMap; +import java.util.Map; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.converters.DataConverter; + + +/** + * ScopeProtocol is universal protocol to serialize any {@link GenericScope} instance. The condition of use is public constructor with arguments {@link Map} and Object[]!
+ * Note: This protocol is unique in some way because it works for read only because scopes are normally serialized via {@link DataConverter} meaning calling serialize method will throw exception right away! But under normal circumstances protocols like this should not exist! + * + * @author PETO + * + * @since 1.2.2 + */ +public class ScopeProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(GenericScope object) throws Exception + { + if (object.getClass() != Scope.class) + return new Object[] {object.castTo(Scope.class)}; + throw new UnsupportedOperationException(getClass().getSimpleName() + ": You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!"); + } + + @Override + public GenericScope unserialize(Class> objectClass, Object... args) throws Exception + { + if (args.length == 1 && args[0] instanceof GenericScope) + { + if (objectClass == args[0].getClass()) + return (GenericScope) args[0]; + return objectClass.getConstructor(Map.class, Object[].class).newInstance(((GenericScope) args[0]).toVarMap(), ((GenericScope) args[0]).toValArray()); + } + return objectClass.getConstructor(Map.class, Object[].class).newInstance(new HashMap<>(), args); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) GenericScope.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java new file mode 100644 index 0000000..3c35d90 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java @@ -0,0 +1,22 @@ +package org.ugp.serialx.protocols; + +import java.io.Serializable; + +/** + * This is based on pretty similar concept as regular {@link Serializable} is! However this interface is meant to create its instance programmatically via constructor! + * So condition of using this is that array of objects returned by {@link SelfSerializable#serialize()} must be applicable for some public constructor of certain class implementing this! + * Specific instances of this interface will be created by calling that public constructor! This is done reflectively by {@link SelfSerializableProtocol}! + * + * @author PETO + * + * @since 1.2.2 + */ +public interface SelfSerializable +{ + /** + * @return Array of objects that can be applied to certain public constructor of this class! This constructor will be then used as unserialize method and will be called during unserialization! + * + * @since 1.2.2 + */ + public Object[] serialize(); +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java new file mode 100644 index 0000000..466a06c --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java @@ -0,0 +1,31 @@ +package org.ugp.serialx.protocols; + +/** + * SelfSerializableProtocol is universal protocol to serialize any {@link SelfSerializable} instance. The condition of use is implementation of {@link SelfSerializable} interface and public constructor that can be called with content returned by specific {@link SelfSerializable#serialize()}! + * + * @author PETO + * + * @since 1.2.2 + * + * @see UniversalObjectInstantiationProtocol + */ +public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol +{ + @Override + public Object[] serialize(SelfSerializable object) + { + return object.serialize(); + } + + @Override + public Class applicableFor() + { + return SelfSerializable.class; + } + + @Override + public byte getMode() + { + return MODE_ALL; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java new file mode 100644 index 0000000..16e65ba --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -0,0 +1,450 @@ +package org.ugp.serialx.protocols; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Serializer; + +/** + * This class supposed to be used for serializing and unserializing objects in Java by turning them in to array of Objects that can be serialized by {@link Serializer} or used by some higher entities. Also this class is capable of turning array of these objects back in to that very same Object!
+ * {@link SerializationProtocol#unserialize(Class, Object...)} and {@link SerializationProtocol#serialize(Object)} are used for this conversion. + * Instance of SerializationProtocol should be registered into {@link SerializationProtocol#REGISTRY} in order to work, also only one instance of each SerializationProtocol should be used and accessed via this registry!
+ * Note: Protocols should not be serializable in any way!
+ * + * @author PETO + * + * @param | Generic type of object to use protocol for. + * + * @since 1.0.0 + */ +public abstract class SerializationProtocol +{ + /** + * This is serialization protocol registry. This is place where your {@link SerializationProtocol} implementations should be registered in order to work properly! Do not add there two protocols applicable for exactly same classes! + * Also I recommend to register protocols in generic order of object that are they applicable for! In other words If some object Foo has child classes, protocol of these classes should be registered after each other. + * Defaultly there are registered protocols from ugp.org.SerialX.protocols. + * + * @since 1.3.0 + */ + public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(new UniversalObjectInstantiationProtocol(), new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); + + /** + * This mode is for protocols that are used for serialization only! + * + * @since 1.3.5 + */ + public static final byte MODE_SERIALIZE = 0; + + /** + * This mode is for protocols that are used for deserialization only! + * + * @since 1.3.5 + */ + public static final byte MODE_DESERIALIZE = 1; + + /** + * This mode is for protocols that chat can both serialize and deserialize! + * + * @since 1.3.5 + */ + public static final byte MODE_ALL = 2; + + protected boolean isActive = true; + + @Override + public boolean equals(Object obj) + { + if (obj instanceof Class) + return applicableFor().equals(obj); + else if (obj instanceof SerializationProtocol) + return applicableFor().equals(((SerializationProtocol) obj).applicableFor()); + return super.equals(obj); + } + + @Override + public String toString() + { + return getClass().getName() + "[" + applicableFor().getName() + "]"; + } + + /** + * @param object | The object. + * + * @return Array of objects to serialize created from given object. + * + * @since 1.0.0 + */ + public abstract Object[] serialize(T object) throws Exception; + + /*/** + * @param object | The object. + * @param scope | Scope to use! + * + * @return Scope of object to serialize created from given object. + * Note: Do not use WORK IN PROGRESS! + * + * @since 1.2.2 + * + public Scope serializeAsScope(T object) + { + return null; + }*/ + + /** + * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. This supposed to be an instance of object, not null! + * + * @throws Exception you can just pass exception to Serializer if you are not interested in handling it on your own. + * + * @since 1.0.0 + */ + public abstract T unserialize(Class objectClass, Object... args) throws Exception; + + /*/** + * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! + * @param scope | Scope with data to create {@link T} from. + * + * @return New instance of object {@link T} created from scopeOfArgs. + * + * @since 1.2.0 + * + public T unserialize(Class objectClass, Scope scope) throws Exception + { + return null; + }*/ + + /** + * @return Class that can be serialized using this protocol. + * In other words it should return class of object {@link T} + * + * @since 1.0.0 + */ + public abstract Class applicableFor(); + + /** + * @return Mode of this protocol. Default is {@link SerializationProtocol#MODE_ALL}! + * + * @see SerializationProtocol#MODE_ALL + * @see SerializationProtocol#MODE_DESERIALIZE + * @see SerializationProtocol#MODE_SERIALIZE + * + * @since 1.3.5 + */ + public byte getMode() + { + return MODE_ALL; + } + + /** + * @return True if this protocol is active. + * Only active protocols can be used! + * + * @since 1.0.0 + */ + public boolean isActive() + { + return isActive; + } + + /** + * @param isActive | Set this on true to activate this protocol or set this on false to deactivate it so it will not be used. + * This can be useful for example when you want to force program to serialize java.io.Serializable object using classic java.io.Serializable. + * For example when you deactivate {@link StringProtocol} program will be forced to serialize all Strings via java.io.Serializable. + * + * @since 1.0.0 + */ + public void setActive(boolean isActive) + { + this.isActive = isActive; + } + + /** + * @param object | The object. + * + * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from {@link SerializationProtocol#REGISTRY}. + * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! + * + * @since 1.3.0 + */ + public static Object[] serializeObj(O object) throws Exception + { + return serializeObj(REGISTRY, object); + } + + /** + * @param registry | Registry to use! + * @param object | The object. + * + * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from registry. + * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! + * + * @since 1.3.0 + */ + public static Object[] serializeObj(ProtocolRegistry registry, O object) throws Exception + { + SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE); + if (prot == null) + { + LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); + return null; + } + return prot.serialize(object); + } + + /** + * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. Object will be created via protocol picked from {@link SerializationProtocol#REGISTRY}. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! + * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! + * + * @throws Exception when exception occurs while unserializing object using protocol! + * + * @since 1.3.0 + */ + public static O unserializeObj(Class objectClass, Object... args) throws Exception + { + return unserializeObj(REGISTRY, objectClass, args); + } + + /** + * @param registry | Registry to use! + * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. Object will be created via protocol picked from registry. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! + * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! + * + * @throws Exception when exception occurs while unserializing object using protocol! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public static O unserializeObj(ProtocolRegistry registry, Class objectClass, Object... args) throws Exception + { + SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE); + if (prot == null) + { + LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); + return null; + } + return (O) prot.unserialize(objectClass, args); + } + + /** + * ProtocolRegistry, place to register protocols! + * + * @author PETO + * + * @since 1.0.0 (moved to SerializationProtocol since 1.3.0) + */ + public static class ProtocolRegistry extends Registry> + { + private static final long serialVersionUID = 1L; + + /** + * Constructs an {@link ProtocolRegistry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public ProtocolRegistry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link ProtocolRegistry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public ProtocolRegistry(Collection> c) + { + super(c); + } + + /** + * Constructs an {@link ProtocolRegistry} with protocols. + * + * @param protocols | Initial content of registry. + * + * @since 1.3.0 + */ + public ProtocolRegistry(SerializationProtocol... protocols) + { + super(protocols); + } + + @Override + public ProtocolRegistry clone() + { + return new ProtocolRegistry(this); + } + + @Override + public void add(int index, SerializationProtocol element) + { + if (GetProtocolFor(element.applicableFor()) != null && element.applicableFor() != Object.class) + LogProvider.instance.logErr(getClass().getSimpleName() + ": Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null); + addDuplicatively(index, element); + } + + /** + * @param protocolsClass | Protocols class. + * + * @return Protocol by its class. + * + * @since 1.0.0 + */ + public SerializationProtocol getProtocolByClass(Class> protocolsClass) + { + for (SerializationProtocol p : this) + if (p.getClass().equals(protocolsClass)) + return p; + return null; + } + + /** + * @return Sublist of protocols that are active and can be used. + * + * @since 1.0.0 + */ + public List> GetActiveProtocols() + { + return GetActiveProtocols(MODE_ALL); + } + + /** + * @return Sublist of protocols that are not active and can't be used. + * + * @since 1.0.0 + */ + public List> GetDeactivatedProtocols() + { + return GetDeactivatedProtocols(MODE_ALL); + } + + /** + * @param mode | Mode of protocol to find. + * + * @return Sublist of protocols that are active and can be used according to mode. + * + * @since 1.3.5 + */ + public List> GetActiveProtocols(byte mode) + { + List> resault = new ArrayList<>(); + + for (SerializationProtocol p : this) + if (p.isActive() && (p.getMode() == 2 || p.getMode() == mode)) + resault.add(p); + return resault; + } + + /** + * @param mode | Mode of protocol to find. + * + * @return Sublist of protocols that are not active and can't be used according to mode. + * + * @since 1.3.5 + */ + public List> GetDeactivatedProtocols(byte mode) + { + List> resault = new ArrayList<>(); + + for (SerializationProtocol p : this) + if (!p.isActive() && (p.getMode() == 2 || p.getMode() == mode)) + resault.add(p); + return resault; + } + + /** + * @param + * @param obj | Object that is required protocol applicable for. + * + * @return Protocol applicable for required objects class or null if there is no such an active protocol! + * + * @since 1.0.5 + */ + public SerializationProtocol GetProtocolFor(O obj) + { + return GetProtocolFor(obj, MODE_ALL); + } + + /** + * @param + * @param applicableFor | Class of object that is protocol applicable for. + * + * @return Protocol applicable for required class or null if there is no such an active protocol! + * + * @since 1.0.0 + */ + public SerializationProtocol GetProtocolFor(Class applicableFor) + { + return GetProtocolFor(applicableFor, MODE_ALL); + } + + /** + * @param + * @param obj | Object that is required protocol applicable for. + * @param mode | Mode of protocol to find. + * + * @return Protocol applicable for required objects class according to mode or null if there is no such an active protocol! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public SerializationProtocol GetProtocolFor(O obj, byte mode) + { + return (SerializationProtocol) GetProtocolFor(obj.getClass(), mode); + } + + /** + * @param + * @param applicableFor | Class of object that is protocol applicable for. + * @param mode | Mode of protocol to find. + * + * @return Protocol applicable for required class according to mode or null if there is no such an active protocol! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public SerializationProtocol GetProtocolFor(Class applicableFor, byte mode) + { + SerializationProtocol protocol = null; + for (int i = 0, len = size(), myMode = 0; i < len; i++) + { + SerializationProtocol p = get(i); + if (p.isActive() && ((myMode = p.getMode()) == 2 || myMode == mode)) + { + Class applicable = p.applicableFor(); + if (applicable == applicableFor) + return (SerializationProtocol) p; + else if (applicable.isAssignableFrom(applicableFor)) + protocol = (SerializationProtocol) p; + } + } + return protocol; + } + + /** + * @param isActive | Activity state for all registered protocols. + * + * @since 1.0.0 + */ + public void setActivityForAll(boolean isActive) + { + for (SerializationProtocol p : this) + p.setActive(isActive); + } + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java new file mode 100644 index 0000000..68e1529 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java @@ -0,0 +1,62 @@ +package org.ugp.serialx.protocols; + +/** + * StringProtocol is universal protocol to serialize any {@link CharSequence} instance. The condition of use is public constructor with one {@link String} or byte[] argument. + * + * @author PETO + * + * @since 1.0.0 and universal for {@link CharSequence} since 1.2.0 + */ +public class StringProtocol extends SerializationProtocol +{ + @Override + public Object[] serialize(CharSequence object) + { + int len = object.length(); + Object[] chars = new Object[len]; + + for (int i = 0; i < len; i++) + chars[i] = (int) object.charAt(i); + return chars; + } + + @Override + public CharSequence unserialize(Class objectClass, Object... args) throws Exception + { + if (args.length == 1 && args[0] instanceof CharSequence) + return (CharSequence) args[0]; + + if (objectClass.isInterface()) + objectClass = String.class; + + char[] chars = new char[args.length]; + for (int i = 0; i < args.length; i++) + if (args[i] != null) + { + if (args[i] instanceof Character) + chars[i] = (char) args[i]; + else + chars[i] = (char)((Number) args[i]).intValue(); + } + else + break; + + String str = new String(chars); + if (objectClass == String.class) + return str; + try + { + return objectClass.getConstructor(String.class).newInstance(str); + } + catch (Exception e) + { + return objectClass.getConstructor(char[].class).newInstance(chars); + } + } + + @Override + public Class applicableFor() + { + return CharSequence.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java new file mode 100644 index 0000000..414c37f --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java @@ -0,0 +1,61 @@ +package org.ugp.serialx.protocols; + +import java.lang.reflect.Constructor; +import java.util.Arrays; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.Serializer; + +/** + * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! + * Note: This protocol is for deserialization only! + * + * @author PETO + * + * @param Generic type of deserialized object! + * + * @since 1.3.5 + */ +public class UniversalObjectInstantiationProtocol extends SerializationProtocol { + + @Override + public Object[] serialize(T object) + { + throw new UnsupportedOperationException(getClass().getSimpleName() + ": This protocol is only for reading! It cant serialize " + object); + } + + @SuppressWarnings("unchecked") + @Override + public T unserialize(Class objectClass, Object... args) throws Exception + { + try + { + return objectClass.getConstructor(Serializer.ToClasses(args)).newInstance(args); + } + catch (Exception e0) + { + for (Constructor cons : objectClass.getConstructors()) + try + { + return (T) cons.newInstance(args); + } + catch (IllegalArgumentException e) + {} + } + LogProvider.instance.logErr(getClass().getSimpleName() + ": Unable to call create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); + return null; + } + + @SuppressWarnings("unchecked") + @Override + public Class applicableFor() + { + return (Class) Object.class; + } + + @Override + public byte getMode() + { + return MODE_DESERIALIZE; + } +} diff --git a/SerialX-json/.classpath b/SerialX-json/.classpath new file mode 100644 index 0000000..002ad57 --- /dev/null +++ b/SerialX-json/.classpath @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/.project b/SerialX-json/.project new file mode 100644 index 0000000..873aaef --- /dev/null +++ b/SerialX-json/.project @@ -0,0 +1,23 @@ + + + SerialX-json + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SerialX-json/.settings/org.eclipse.jdt.core.prefs b/SerialX-json/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..2f5cc74 --- /dev/null +++ b/SerialX-json/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-json/.settings/org.eclipse.m2e.core.prefs b/SerialX-json/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/SerialX-json/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml new file mode 100644 index 0000000..9b6b1be --- /dev/null +++ b/SerialX-json/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + org.ugp + serialx + 1.3.7 + + org.ugp.serialx + json + + SerialX-json + SerialX Json support + + + + org.ugp.serialx + core + 1.3.7 + + + \ No newline at end of file diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java new file mode 100644 index 0000000..f468198 --- /dev/null +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -0,0 +1,403 @@ +package org.ugp.serialx.json; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.JussSerializer; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.BooleanConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.json.converters.JsonCharacterConverter; +import org.ugp.serialx.json.converters.JsonNumberConverter; +import org.ugp.serialx.json.converters.JsonObjectConverter; +import org.ugp.serialx.converters.NullConverter; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.converters.VariableConverter; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + +/** + * This is implementation of {@link JussSerializer} for serializing in Json! + * It should generate and work with .json files! + *

+ * Note: No Json specific syntax checks are made, only some small conventions and formating changes will occur to ensure Json syntax correctness but it will let you to use some Juss features freely so you can easily end up with some Json-juss hybrid! + * + * @author PETO + * + * @since 1.3.2 + */ +@SuppressWarnings("serial") +public class JsonSerializer extends JussSerializer +{ + /** + * This is representation of empty Json array. Use this instead of empty scope during serialization when you want to prevent it being serialized as empty Json object! + *

+ * [] + * + * @since 1.3.5 + */ + public static final String EMPTY_ARRAY = StringConverter.DirectCode("[]"); + + /** + * This is representation of empty Json array. This is how empty scopes will be serialized by default! + *

+ * [] + * + * @since 1.3.5 + * + * @see JsonSerializer#EMPTY_ARRAY + */ + public static final String EMPTY_OBJECT = StringConverter.DirectCode("{}"); + + public static final ParserRegistry JSON_PARSERS = new ParserRegistry(new VariableConverter(true), new StringConverter(), new JsonNumberConverter(), new BooleanConverter(false), new JsonCharacterConverter(false), new NullConverter(), new JsonObjectConverter()); + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public JsonSerializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Map variablesMap, Collection values) + { + this(JSON_PARSERS.clone(), variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, SerializationProtocol.REGISTRY.clone(), variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public JsonSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(parsers, protocols, variablesMap, values, parent); + } + + @Override + public String Var(String name, T value, boolean isValue) + { + return Code((isValue ? "$\"" : "\"") + name + "\" = " + getParsers().toString(value, 0, 0, this, getProtocols(), isGenerateComments()) + (generateComments ? ", //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + } + + @Override + public Object put(String variableName, Object variableValue) + { + if (Serializer.isOneOf(variableName.charAt(0), '"', '\'') && Serializer.isOneOf(variableName.charAt(variableName.length()-1), '"', '\'')) + variableName = variableName.substring(1, variableName.length()-1); + return super.put(variableName, variableValue); + } + + @Override + public JsonSerializer emptyClone(Scope parent) + { + JsonSerializer srl = emptyClone(new JsonSerializer(), parent); + srl.setGenerateComments(isGenerateComments()); + return srl; + } + + @SuppressWarnings("unchecked") + @Override + public S LoadFrom(Reader reader, Object... formatArgs) + { + Scope sc = super.LoadFrom(reader, formatArgs); + + Object jsonScope; + if (sc.valuesCount() == 1 && (jsonScope = sc.get(0)) instanceof Scope) + return (S) jsonScope; + return (S) sc; + } + + @Override + public A SerializeTo(A source, Object... args) throws IOException + { + int tabs = 0; + if (args.length > 1 && args[1] instanceof Integer) + tabs = (int) args[1]; + + if (tabs == 0 && !(valuesCount() == 1 && variablesCount() <= 0 && get(0) instanceof Scope)) + { + JussSerializer scope = emptyClone(null); + scope.add(this); + return scope.SerializeTo(source, args); + } + return super.SerializeTo(source, args); + } + + @Override + public ParserRegistry getParsers() + { + return parsers != null ? parsers : (parsers = JSON_PARSERS.clone()); + } + + /** + * This should append serializedVar into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + @Override + protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException + { + source.append(multilpy('\t', tabs)).append(serializedVar); + if (isLast) + return source; + return source.append(','); + } + + /** + * This should append serializedVal into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + @Override + protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException + { + source.append(multilpy('\t', tabs)).append(serializedVal); + if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, '/') != -1) + return source; + return source.append(','); + } + + @Override + public A SerializeAsSubscope(A source, Object... args) throws IOException + { + return SerializeAsSubscope(source, variablesCount() > 0 ? new char[] {'{', '}'} : new char[] {'[', ']'}, args); + } + + /** + * @param jsonSerializer | JsonSerializer to create {@link JussSerializer} from! + * + * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! + * + * @since 1.3.2 + */ + public static JsonSerializer fromJussSerializer(JussSerializer jussSerializer) + { + if (jussSerializer instanceof JsonSerializer) + return (JsonSerializer) jussSerializer; + try + { + return jussSerializer.transformToScope().clone(JsonSerializer.class); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + /** + * @param jsonSerializer | JsonSerializer to create {@link JussSerializer} from! + * + * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! + * + * @since 1.3.2 (since 1.3.7 moved from {@link JussSerializer} and renamed from "fromJsonSerializer" to "toJussSerializer") + */ + public static JussSerializer toJussSerializer(JsonSerializer jsonSerializer) + { + try + { + if (jsonSerializer.valuesCount() == 1 && jsonSerializer.variablesCount() == 0 && jsonSerializer.get(0) instanceof Scope) + { + GenericScope sc = (GenericScope) jsonSerializer.getScope(0); + if (sc instanceof Serializer) + return ((Serializer) sc).transformToScope().clone(JsonSerializer.class); + return sc.clone(JsonSerializer.class); + } + else + return jsonSerializer.transformToScope().clone(JsonSerializer.class); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + /** + * @param fromObj | Object to create serializer from! + * + * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JsonSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#LoadFrom(CharSequence)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#LoadFrom(File)}
{@link Reader}{@link Serializer#LoadFrom(Reader)}
{@link InputStream}{@link Serializer#LoadFrom(InputStream)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws When something went wrong during deserialization! + * + * @since 1.3.5 + */ + public static JsonSerializer from(Object fromObj) throws Exception + { + try + { + return from(fromObj, new String[0]); + } + catch (IntrospectionException e) + { + return new JsonSerializer(fromObj); + } + } + + /** + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JsonSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#LoadFrom(CharSequence)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#LoadFrom(File)}
{@link Reader}{@link Serializer#LoadFrom(Reader)}
{@link InputStream}{@link Serializer#LoadFrom(InputStream)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + public static JsonSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return (JsonSerializer) Serializer.from(new JsonSerializer(), fromObj, fieldNamesToUse); + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java new file mode 100644 index 0000000..0850e25 --- /dev/null +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java @@ -0,0 +1,28 @@ +package org.ugp.serialx.json.converters; + +import org.ugp.serialx.converters.CharacterConverter; + +public class JsonCharacterConverter extends CharacterConverter { + + protected boolean formatAsString; + + public JsonCharacterConverter(boolean formatAsString) { + setFormatAsString(formatAsString); + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Character) + return isFormatAsString() ? obj.toString() : String.valueOf((int) (char) obj); + return CONTINUE; + } + + public boolean isFormatAsString() { + return formatAsString; + } + + public void setFormatAsString(boolean formatAsString) { + this.formatAsString = formatAsString; + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java new file mode 100644 index 0000000..4850d18 --- /dev/null +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -0,0 +1,14 @@ +package org.ugp.serialx.json.converters; + +import org.ugp.serialx.converters.NumberConverter; + +public class JsonNumberConverter extends NumberConverter { + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Number) + return decimalFormatter != null ? decimalFormatter.format(obj) : obj.toString(); + return CONTINUE; + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java new file mode 100644 index 0000000..255591d --- /dev/null +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -0,0 +1,48 @@ +package org.ugp.serialx.json.converters; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.ArrayConverter; +import org.ugp.serialx.converters.ObjectConverter; +import org.ugp.serialx.json.JsonSerializer; +import org.ugp.serialx.protocols.SerializationProtocol; + +/** + * Used internally by {@link JsonSerializer} to ensure proper and valid Json format for scopes and protocols. + * + * @author PETO + * + * @since 1.3.5 + */ +public class JsonObjectConverter extends ObjectConverter +{ + @SuppressWarnings("unchecked") + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + if (arg.getClass().isArray()) + arg = new Scope(ArrayConverter.fromAmbiguous(arg)); + + SerializationProtocol prot = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args); + + if (prot != null && !(arg instanceof Scope)) + try + { + Object[] objArgs = prot.serialize(arg); + if (objArgs.length == 1 && objArgs[0] instanceof Scope) + return super.toString(myHomeRegistry, objArgs[0], args); + else + return super.toString(myHomeRegistry, new Scope(objArgs), args); + } + catch (Exception e) + {} + + return super.toString(myHomeRegistry, arg, prot, args); + } + + @Override + public Serializer getPreferredSerializer() + { + return new JsonSerializer(); + } +} \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c9a8d30 --- /dev/null +++ b/pom.xml @@ -0,0 +1,58 @@ + + 4.0.0 + + org.ugp + serialx + 1.3.7 + pom + + + SerialX-json + SerialX-core + + + SerialX root + Store Java objects into file via SerialX. SerialX is a powerful utility library to serialize objects in Java programmatically via recursive descent parser for custom domain-specific languages! + https://github.com/SimplyProgrammer/Java-SerialX + + + + Custom license + https://github.com/SimplyProgrammer/Java-SerialX/blob/master/LICENSE + + + + + + SimplyProgrammer + petko.hupka@gmail.com + org.ugp + https://github.com/SimplyProgrammer/ + + + + + scm:git:git://github.com/SimplyProgrammer/Java-SerialX.git + scm:git:ssh://github.com:SimplyProgrammer/Java-SerialX.git + https://github.com/SimplyProgrammer/ + + + + 1.8 + 1.8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.8 + 1.8 + + + + + \ No newline at end of file From 234b2fdb37cd2bc9e1245f5823293e3e51af2222 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 26 Jun 2023 16:06:08 +0200 Subject: [PATCH 04/75] further modularization and bug fixes --- .classpath | 9 + .project | 6 + .settings/org.eclipse.core.resources.prefs | 2 + .settings/org.eclipse.jdt.core.prefs | 8 + Changelog.md | 211 ------------------ .../org.eclipse.core.resources.prefs | 6 + SerialX-core/pom.xml | 6 +- .../java/org/ugp/serialx/GenericScope.java | 2 +- .../java/org/ugp/serialx/JussSerializer.java | 47 +++- .../main/java/org/ugp/serialx/Registry.java | 44 +++- .../src/main/java/org/ugp/serialx/Scope.java | 15 +- .../main/java/org/ugp/serialx/Serializer.java | 42 ++-- .../ugp/serialx/converters/DataParser.java | 3 +- .../serialx/converters/NumberConverter.java | 6 +- .../serialx/converters/ObjectConverter.java | 2 +- .../serialx/converters/imports/Import.java | 10 +- .../ugp/serialx/protocols/MapProtocol.java | 7 + SerialX-devtools/.classpath | 38 ++++ SerialX-devtools/.project | 23 ++ .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../.settings/org.eclipse.m2e.core.prefs | 4 + SerialX-devtools/pom.xml | 23 ++ .../devtools}/SerializationDebugger.java | 169 +------------- .../converters/DebugParserRegistry.java | 165 ++++++++++++++ .../org.eclipse.core.resources.prefs | 6 + SerialX-json/pom.xml | 8 +- SerialX-operators/.classpath | 38 ++++ SerialX-operators/.project | 23 ++ .../org.eclipse.core.resources.prefs | 6 + .../.settings/org.eclipse.jdt.core.prefs | 8 + .../.settings/org.eclipse.m2e.core.prefs | 4 + SerialX-operators/pom.xml | 23 ++ .../org/ugp/serialx/converters/Operators.java | 69 ++++++ .../operators/ArithmeticOperators.java | 0 .../operators/ComparisonOperators.java | 0 .../ConditionalAssignmentOperators.java | 0 .../operators/LogicalOperators.java | 2 +- .../operators/NegationOperator.java | 0 pom.xml | 39 +++- 40 files changed, 650 insertions(+), 438 deletions(-) create mode 100644 .classpath create mode 100644 .settings/org.eclipse.core.resources.prefs create mode 100644 .settings/org.eclipse.jdt.core.prefs delete mode 100644 Changelog.md create mode 100644 SerialX-core/.settings/org.eclipse.core.resources.prefs create mode 100644 SerialX-devtools/.classpath create mode 100644 SerialX-devtools/.project create mode 100644 SerialX-devtools/.settings/org.eclipse.core.resources.prefs create mode 100644 SerialX-devtools/.settings/org.eclipse.jdt.core.prefs create mode 100644 SerialX-devtools/.settings/org.eclipse.m2e.core.prefs create mode 100644 SerialX-devtools/pom.xml rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-devtools/src/main/java/org/ugp/serialx/devtools}/SerializationDebugger.java (63%) create mode 100644 SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java create mode 100644 SerialX-json/.settings/org.eclipse.core.resources.prefs create mode 100644 SerialX-operators/.classpath create mode 100644 SerialX-operators/.project create mode 100644 SerialX-operators/.settings/org.eclipse.core.resources.prefs create mode 100644 SerialX-operators/.settings/org.eclipse.jdt.core.prefs create mode 100644 SerialX-operators/.settings/org.eclipse.m2e.core.prefs create mode 100644 SerialX-operators/pom.xml create mode 100644 SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java rename {SerialX-core => SerialX-operators}/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java (100%) rename {SerialX-core => SerialX-operators}/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java (100%) rename {SerialX-core => SerialX-operators}/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java (100%) rename {SerialX-core => SerialX-operators}/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java (99%) rename {SerialX-core => SerialX-operators}/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java (100%) diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..bd36355 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.project b/.project index bbfcc34..fd37aa3 100644 --- a/.project +++ b/.project @@ -5,6 +5,11 @@ + + org.eclipse.jdt.core.javabuilder + + + org.eclipse.m2e.core.maven2Builder @@ -12,6 +17,7 @@ + org.eclipse.jdt.core.javanature org.eclipse.m2e.core.maven2Nature diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..2f5cc74 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/Changelog.md b/Changelog.md deleted file mode 100644 index ab29a47..0000000 --- a/Changelog.md +++ /dev/null @@ -1,211 +0,0 @@ -# SerialX 1.0.0 (beta) - -Release date: 8.14.2020 (Evening) - -What was added: -* Serializer utility class. -* 2 build-in protocols. -# - -# SerialX 1.0.5 (beta) - -Release date: 8.20.2020 (Night) - -What was added: -* Ability to generate comments. -* Fixing some small bugs. -# - -# SerialX 1.0.6 - -Release date: 8.22.2020 (Noon) - -What was added: -* Improveing way to serialize numbers. -* Adding suffixes fot double "d", short "s" and byte "y"! -* Java Base64 serialized object now does not need to start with "#"! -* Objects serialized using protocol with no arguments will now not by serialized with null argument! -* Repairing an error with long suffix! -# - -# SerialX 1.1.0 - -Release date: 9.22.2020 (Afternoon) - -What was added: -* Adding decimal number formatter! -* "unserialize" method in SerializationProtocol now throws Exception which makes reflection stuff easier! -* Fixing some problems such as "Too big objects simply disappear during serialization!" -* Better optimization. Improving the performance of Serializing and Unserializing astronomically! -* Some characters now can be serialized using regular Java way for example 'a'! However SerialX syntax characters such as { or } must be still serialized using ASCII code! -Numbers must have additional character behind for example '4/' otherwise they will be taken as ASCII code! -* Some new methods and stuff! -# - -# SerialX 1.1.2 - -Release date: 9.27.2020 (Evening) - -What was added: -* Integers now can be serialized using Java binary and hexadecimal form (0b1111, 0xffff)! -* Numbers can be separated with underscore (just like in Java)! -* Fixing the bug when formatter mess up decimals suffixes and integers! -# - -# SerialX 1.1.5 - -Release date: 12.6.2020 (Evening) - -What was added: -* Variable system! Now "order" is not only possibility. -* Functions working with variable system! -* Functions that allows you to insert custom code (comments and stuff)! -* Fixing "long-lived" bugs such as the on with double slash comment, hopefuly for the last! -# - -# SerialX 1.2.0_pre - V2 - -Release date: 3.18.2021 (Afternoon) - -What was added: -* New Scope object that are now values and variables loaded in to so now its not necesarry to load indepednent values and variables separatly! -* Scope is the physical manifestation of loaded content in your program! -* Ability to create sub-scopes / neasted scopes in side of parent scopes or file itself similarly to JSON! For example: { \/\*scope\*\/ } -* Ability to serialize string normaly in quotes like in java! But certain syntactical characters from SerialX cant be present! -* "splitValues" method was removed becasue it was out of purpous of library itself. -* Comma now works as semicolon! -* Tremendous reading performence boost! Large quantity reading is now up to 50x faster than in previous version. -* Fixing a bug when order of elements being messed up during serialization. -* Fixing a bug with hexadecimal and binary number formats. -* Fixing some other less important bugs. -* Note: Since this is pre release, there are probably some bugs but hopefully nothing totaly broken. Also this prerelease can only read scopes, not write! -# - -# SerialX 1.2.2 - -Release date: 4.11.2021 (Afternoon) - -What was added: -* Ability to serialize Scope object! -* Ability to clone Objects using Serializer! -* Ability to instantiate any object using Serializer by calling shortest public constructor! -* Now you can access Java utility from SerialX, you can invoke public static methods and fields directly from SerialX! -* SelfSerializable interface which gives you ability to serialize objects without protocol by calling public constructors! -* Static field "new" to obtain clone of variable and "class" to obtain class of variables value! -* 4 new protocols: - * MapProtocol - to serialize maps! - * ScopeProtocol (reading only) to read scopes using protocol! - * AutoProtocol - will automatically serialize selected fields with getters and setters! - * EnumProtocol - to serialize any java enum! - * SelfSerializableProtocol - operates with SelfSerializable interface! -* Tremendous writing performance boost! Large quantity writing is now up to 80x faster than in previous version. -* Eliminating usage of Regex completely which results into even faster reading! -* Now you can access variables of scopes by "." directly in SerialX! -* Fixing bug when blank characters despair from string, also now string can contains any character except quote and nextline! -* SerialX API is now partially opensource, the sources are included in main Jar, however according to the License you cant appropriate any of this code without including its origins! -# - -# SerialX 1.2.5 - -Release date: 4.11.2021 (Afternoon) - -What was added: -* Serializer can now serialize into any Appendable which includes all Writers, StringBuilder and many others which gives you a lot of opportunities! -* Serializer can now read from any CharSequence or any Reader object! -* Serializer is now fully capable of reading JSON! -* Serializer can read specific object or variable while ignoring any other stuff which saves a lot of performance (this is experimental)! -* Slight increase of reading performance! -* Utility to work with JSON like JsonScope! -* A lot of new utility in Scope object such as filtering or object transformation! -* Small bugs fixed! -# - -# SerialX 1.3.0 - -Release date: 8.8.2021 (Night) - -What was added: -* Revelation of compiler that is now Recursive descent parser that is customizable and configurable. -* Structure of entire API was generally reorganized in to 3 main sections: - * Serializer - which is main class that operates entire API. Is responsible for input and output, formatting and general utility! - * DataParser and DataConverter API - is recursive descent parser itself that is responsible for converting objects to strings and parsing them back! In default SerialX API implementation now known as JUSS (Java universal serial script) are these parsers and converters available: - * NumberConverter - for converting and parsing numbers (integers, decimals, hexa, bin)! - * BooleanConverter - for converting and parsing booleans! - * CharacterConverter - for converting and parsing chars! - * StringConverter - for converting and parsing strings ("Hello world!", "And others...")! - * NullConverter - for converting and parsing null! - * ObjectConverter - for converting and parsing SerializationProtocol expressions and Scopes! - * VariableConverter - for converting and parsing JUSS variables (Map.Entry)! - * SerializableBase64Converter - for converting and parsing Base64 expressions (java.io.Serializable)! - * ArrayConverter - for converting and parsing primitive arrays! - ## - * OperationGroups - for parsing expression groups such as (5 + 5) / 2 - * ArithmeticOperators - for parsing arithmetic expression such as 2 + 5 * 4 ** 2 - * LogicalOperators - for parsing logical expression such as true && false || true - * ComparisonOperators - for comparing objects, for instance 6 > 5 - * ConditionalAssignmentOperators - that provides ternary operator (?:) and null coalescing (??) - * NegationOperator - to negate stuff, for example !true - ## - * As mentioned. you can create your own parsers or even replace already existing ones with yours! - * SerializationProtocol API - long known protocol system for more complex objects. It contains 8 protocols as before! Now protocols are operated by ObjectConverter! -* New import system that allows you to import some class once with certain alias and then use it with that alias, similar to java! -* Too big integers are now automatically converted into long without necessarily of using L suffix! -* Small new syntax features and alot of small enhancements (shortened version of variable being initialized to scope)! -* Alot of string utility methods from Serializer become public and some were moved into converters where they are mainly used! -* Registry object which is Collection type that can store only one instance per class! -* Some new functions in Scope! -* Deprecated methods were removed! -* Source code was excluded from main jar to save space and is now available in separate src.zip file! Now on java doc files will not be provided and src.zip should be used instead! -* Small bugs fixed but there were alot of internal changes in this update so they might be another bugs so I encourage you to report any bug you encounter! -# - -# SerialX 1.3.2 - -Release date: 10.25.2021 (Morning) - -What was added: -* Serializer now abstract class which inherits Scope so now it is Scope that can serialize itself! Serialization and deserialization methods are now not static and original functionality has been split into two separated objects that inherit Serializer: - * JussSerializer - which is responsible for serializing and deserializing objects using Juss format (original functionality of Serializer). - * JsonSerializer - which is responsible for serializing and deserializing objects using Json format (successors of JsonSelxUtils) -* JsonSelxUtils was replaced with JsonSerializer that is capable of both reading and writing Json! -* Main formatting and reading algorithms can be now overridden by extending JsonSerializer, JussSerializer or Serializer! -* Ability to set multiple variables on one value, for example x = y = z = 5 -* Ability to remove multiple variables by setting them on null! -* Variables of scope are now settable from outer world, for example someScope.x = 9 -* Compare identity operator (triple equals) was added and transtype comparison logic was changed, mainly between primitive datatypes! -* Logical operators now have higher precedence over comparison operators by default! -* Logic behind operators can now be overridden by extending belonging operator DataParser! -* Adding some new utility and functionalities! -* Small syntax features (scopes now don't have to be separated with semicolon if they are in new line)! -* Package name was renamed from "ugp.org.SerialX" to "org.ugp.serialx"! -* Fixing some bugs with formatting and reading! -# - -# SerialX 1.3.5 - -Release date: imminent... - -What was added: -* Scope was split into 2 separate classes: - * GenericScope - that allows you to set generic types of keys and values. Furthermore, it can be serialized with generic types preserved! - * Scope - that you already know which poses the same functionality as before now as a child class of GenericScope! -* Imports system was redesigned and splitted into multiple separate classes, each handling some part of functionality! - * Also imports are now Serializer specific rather than global! -* Precedence of ConditionalAssignmentOperators ?: and ?? was slightly altered to closely resemble behavior of these operators in other languages. Also, these operators now can be nested without necessity of (). -* Parser API (DataParser and DataConverter) was redesigned and is now handled by ParserRegistry which can provide additional functionality such as caching to improve performance! -* Serialization syntax of Serializable objects using Base64 via SerializableBase64Converter was slightly altered to mitigate conflicts with the rest of JUSS syntax! -* New "from/into API" which is now part of the Scope that allows you to map almost any java object into a scope and any scope into corresponding java object! -* AutoProtocol is now based on "from/into API" making it more flexible! -* New UniversalObjectInstantiationProtocol that can deserialize any object by calling its constructor (something similar to ObjectClass::new)! -* SerializationProtocols now have a "mode" that can define what they can do! -* JsonSerializer will now serialize JUSS protocols as JSON objects to achieve more JSON compatibility out of the box! -* LogProvider which is now responsible for logging errors and allows you to implement your own form of logging! -* SerializationDebugger that provides ability to debug serialization and deserialization! -* New utility across API and small new functionalities and changes! -* Fixing bugs (hopefully not adding new ones): - * Long live bug with // and /* comments in strings now fixed for good (I hope...) - * Bug with wrong formatting when serializing Json in Juss and revers! - * Some other small ones! -* New examples were added! -* Source code is now also available in "dev" branch! -# diff --git a/SerialX-core/.settings/org.eclipse.core.resources.prefs b/SerialX-core/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/SerialX-core/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index d26d70a..561fa3b 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -3,11 +3,13 @@ org.ugp serialx - 1.3.7 + ${revision} + org.ugp.serialx core + 1.3.7 - SerialX-core + SerialX core Core of SerialX \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 0cd2c1f..9ad062b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -314,7 +314,7 @@ public boolean containsIndependentValue(ValT value) * @since 1.2.0 */ @SuppressWarnings("unchecked") - public V get(int valueIndex) + public V get(int valueIndex) { V obj = (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); return obj instanceof Serializer.NULL ? null : obj; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java index 05e85fd..008607d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java @@ -25,16 +25,11 @@ import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; import org.ugp.serialx.converters.ObjectConverter; -import org.ugp.serialx.converters.StringConverter; import org.ugp.serialx.converters.imports.ImportConverter; -import org.ugp.serialx.converters.operators.ArithmeticOperators; -import org.ugp.serialx.converters.operators.ComparisonOperators; -import org.ugp.serialx.converters.operators.ConditionalAssignmentOperators; -import org.ugp.serialx.converters.operators.LogicalOperators; +import org.ugp.serialx.converters.imports.ImportConverter.Imports; +import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import javafx.beans.binding.When; - /** * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! * It should generate and work with .juss or .srlx files! @@ -44,17 +39,39 @@ * @since 1.3.2 */ @SuppressWarnings("serial") -public class JussSerializer extends Serializer +public class JussSerializer extends Serializer implements ImportsProvider { - public static final ParserRegistry JUSS_PARSERS = DataParser.REGISTRY.clone(), JUSS_PARSERS_AND_OPERATORS; + /** + * {@link ParserRegistry} with all parsers required to parse JUSS! + * + * @since 1.3.2 + */ + public static final ParserRegistry JUSS_PARSERS = DataParser.REGISTRY.clone(); + + /** + * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. + *
+ * Since 1.3.7 this requires "org.ugp.serialx.converters.Operators" from SerialX "operators" modules to be present on the classpath! + * + * @since 1.3.2 + */ + public static final ParserRegistry JUSS_PARSERS_AND_OPERATORS; static { JUSS_PARSERS.add(0, new ImportConverter()); JUSS_PARSERS_AND_OPERATORS = JUSS_PARSERS.clone(); - JUSS_PARSERS_AND_OPERATORS.addAllBefore(StringConverter.class, true, new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators()); + + try + { + InvokeStaticFunc(Class.forName("org.ugp.serialx.converters.Operators"), "install", JUSS_PARSERS_AND_OPERATORS); + } + catch (Exception e) + {} } + protected Imports imports; + /** * Set this on true and program will generate comments and report!
* Note: Keep this on false to achieve the best performance! @@ -158,6 +175,14 @@ public ParserRegistry getParsers() return parsers != null ? parsers : (parsers = JUSS_PARSERS.clone()); } + @Override + public Imports getImports() + { + if (imports == null) + imports = ImportConverter.IMPORTS.clone(); + return imports; + } + /** * @param absoluteClone | If true this scope will be cloned using {@link Serializer#Clone(Object, Registry, Object[], Object...)}, if false {@link Scope#clone()}! * @@ -785,7 +810,7 @@ Obtained serializer content (return) * - * @throws When something went wrong during deserialization! + * @throws If something went wrong during deserialization! * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java index ba26bc7..0681b36 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java @@ -183,11 +183,13 @@ public void addAll(@SuppressWarnings("unchecked") Class... elms) throws Excep * @param cls | Class to find! * @param element | Element to insert before index of required class! * + * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} + * * @since 1.3.0 */ - public void addBefore(Class cls, E element) + public int addBefore(Class cls, E element) { - addBefore(cls, false, element); + return addBefore(cls, false, element); } /** @@ -195,21 +197,26 @@ public void addBefore(Class cls, E element) * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! * @param element | Element to insert before index of required class! * + * @return {@link Registry#indexOf(Class, boolean)} + * * @since 1.3.0 */ - public void addBefore(Class cls, boolean includeChildrens, E element) + public int addBefore(Class cls, boolean includeChildrens, E element) { - int index = indexOf(cls); + int index = indexOf(cls, includeChildrens); if (index <= -1) add(element); else add(index, element); + return index; } /** * @param cls | Class to find! * @param element | Element to insert after index of required class! * + * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} + * * @since 1.3.0 */ public void addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element) @@ -222,26 +229,31 @@ public void addAllBefore(Class cls, @SuppressWarnings("unchecked") * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! * @param element | Element to insert after index of required class! * + * @return {@link Registry#indexOf(Class, boolean)} + * * @since 1.3.0 */ - public void addAllBefore(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + public int addAllBefore(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) { - int index = indexOf(cls); + int index = indexOf(cls, includeChildrens); if (index <= -1) addAll(element); else addAll(index, element); + return index; } /** * @param cls | Class to find! * @param element | Element to insert after index of required class! * + * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} + * * @since 1.3.0 */ - public void addAfter(Class cls, E element) + public int addAfter(Class cls, E element) { - addAfter(cls, false, element); + return addAfter(cls, false, element); } /** @@ -249,26 +261,31 @@ public void addAfter(Class cls, E element) * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! * @param element | Element to insert after index of required class! * + * @return {@link Registry#indexOf(Class, boolean)} + * * @since 1.3.0 */ - public void addAfter(Class cls, boolean includeChildrens, E element) + public int addAfter(Class cls, boolean includeChildrens, E element) { int index = indexOf(cls, includeChildrens); if (index <= -1) add(element); else add(index + 1, element); + return index; } /** * @param cls | Class to find! * @param element | Element to insert after index of required class! * + * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} + * * @since 1.3.0 */ - public void addAllAfter(Class cls, @SuppressWarnings("unchecked") E... element) + public int addAllAfter(Class cls, @SuppressWarnings("unchecked") E... element) { - addAllAfter(cls, false, element); + return addAllAfter(cls, false, element); } /** @@ -276,15 +293,18 @@ public void addAllAfter(Class cls, @SuppressWarnings("unchecked") E * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! * @param element | Element to insert after index of required class! * + * @return {@link Registry#indexOf(Class, boolean)} + * * @since 1.3.0 */ - public void addAllAfter(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + public int addAllAfter(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) { int index = indexOf(cls, includeChildrens); if (index <= -1) addAll(element); else addAll(index + 1, element); + return index; } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index baa1551..6cadf3c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1,5 +1,7 @@ package org.ugp.serialx; +import static org.ugp.serialx.converters.DataParser.VOID; + import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Array; @@ -10,12 +12,11 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Map.Entry; +import java.util.Objects; import java.util.function.Predicate; import org.ugp.serialx.converters.ArrayConverter; -import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -295,8 +296,7 @@ public String getString(String variableName) */ public String getString(String variableName, String defaultValue) { - Object obj = get(variableName, defaultValue); - return obj == null ? null : obj.toString(); + return String.valueOf(get(variableName, defaultValue)); } /** @@ -475,8 +475,7 @@ else if (obj instanceof CharSequence) */ public String getString(int valueIndex) { - Object obj = get(valueIndex); - return obj == null ? null : obj.toString(); + return String.valueOf(get(valueIndex)); } /** @@ -1206,8 +1205,8 @@ public static T into(T obj, GenericScope fromScope, List) fromScope).get(var.getName(), DataParser.VOID); - if (varValue != DataParser.VOID) + Object varValue = ((GenericScope) fromScope).get(var.getName(), VOID); + if (varValue != VOID) var.getWriteMethod().invoke(obj, varValue); } return obj; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 6c0fe08..9bd75d3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -40,9 +40,6 @@ import org.ugp.serialx.converters.NumberConverter; import org.ugp.serialx.converters.SerializableBase64Converter; import org.ugp.serialx.converters.StringConverter; -import org.ugp.serialx.converters.imports.ImportConverter; -import org.ugp.serialx.converters.imports.ImportConverter.Imports; -import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -56,7 +53,7 @@ * @since 1.0.0 */ @SuppressWarnings("serial") -public abstract class Serializer extends Scope implements ImportsProvider +public abstract class Serializer extends Scope { /** * Common parsers that can parse primitive datatypes! @@ -67,7 +64,6 @@ public abstract class Serializer extends Scope implements ImportsProvider protected ParserRegistry parsers; protected ProtocolRegistry protocols; - protected Imports imports; /** * @param values | Initial independent values to be added in to this scope! @@ -199,14 +195,6 @@ public T into(Object obj, String... fieldNamesToUse) throws IntrospectionExc return Serializer.into(obj, this, fieldNamesToUse); } - @Override - public Imports getImports() - { - if (imports == null) - imports = ImportConverter.IMPORTS.clone(); - return imports; - } - /** * @param name | Name of variable. * @param value | Value of variable. @@ -887,6 +875,34 @@ else if (ch == '}' || ch == ']') LogProvider.instance.logErr("Variable " + varName + " was not found!"); return null; }*/ + + /** + * @param indexWithStringValue | Index of independent value that should be string. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from string at given index, using parsers of this {@link Serializer}! + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public T getParsed(int indexWithStringValue, Object... args) + { + return (T) getParsers().parse(getString(indexWithStringValue), args); + } + + /** + * @param variableWithStringValue | Variable name with string value. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from value of given variable, using parsers of this {@link Serializer}! + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public T getParsed(String variableWithStringValue, Object... args) + { + return (T) getParsers().parse(getString(variableWithStringValue), args); + } /** * @param f | Source file. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 37738bd..d50616c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -5,7 +5,6 @@ import org.ugp.serialx.LogProvider; import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; -import org.ugp.serialx.converters.operators.NegationOperator; /** * This class supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! @@ -43,7 +42,7 @@ public interface DataParser * @since 1.3.0 */ //TODO ParserRegistry - public static final ParserRegistry REGISTRY = new ParserRegistry(new OperationGroups(), new VariableConverter(), /*new ConditionalAssignmentOperators(), new ComparisonOperators(), new LogicalOperators(), new ArithmeticOperators(),*/ new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new NegationOperator(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + public static final ParserRegistry REGISTRY = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 9936c63..dc69f63 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -8,7 +8,6 @@ import java.util.Locale; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.converters.operators.NegationOperator; /** * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! @@ -106,9 +105,6 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) try { Number integer; - boolean isNeg = arg.charAt(0) == '-'; - if (isNeg) - arg = arg.substring(1); if (arg.endsWith("l")) integer = new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); else if (arg.endsWith("s")) @@ -117,7 +113,7 @@ else if (arg.endsWith("y")) integer = new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10)); else integer = new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - return isNeg ? NegationOperator.negate(integer) : integer; + return integer; } catch (NumberFormatException e) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java index 59e55c8..02c0f90 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java @@ -299,7 +299,7 @@ else if (args.length > 0 && args[0] instanceof Serializer) StringBuilder sb = new StringBuilder(); GenericScope parent; if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) - sb.append(serializer.getImports().getAliasFor(arg.getClass()) + " "); + sb.append(ImportsProvider.getAliasFor(serializer, getClass()) + " "); return serializer.SerializeAsSubscope(sb, args); } catch (IOException e) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java index 66755ad..5ea69be 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -1,5 +1,7 @@ package org.ugp.serialx.converters.imports; +import java.lang.reflect.Type; + import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.imports.ImportConverter.Imports; @@ -13,7 +15,7 @@ * * @see Import */ -public class Import implements Cloneable +public class Import implements Cloneable, Type { protected final Class cls; protected final String alias; @@ -92,6 +94,12 @@ public Import clone() return new Import(getCls(), getClsAlias(), getOwner()); } + @Override + public String getTypeName() + { + return getClsAlias(); + } + public Import clone(ImportsProvider newOwner) { return new Import(getCls(), getClsAlias(), newOwner); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java index 47af7e3..54fab5a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java @@ -8,6 +8,13 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; +/** + * ListProtocol is universal protocol to serialize any {@link Map} instance. The condition of use is public constructor with one {@link Map} argument. + * + * @author PETO + * + * @since 1.2.2 + */ public class MapProtocol extends SerializationProtocol> { @Override diff --git a/SerialX-devtools/.classpath b/SerialX-devtools/.classpath new file mode 100644 index 0000000..002ad57 --- /dev/null +++ b/SerialX-devtools/.classpath @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-devtools/.project b/SerialX-devtools/.project new file mode 100644 index 0000000..b5f340d --- /dev/null +++ b/SerialX-devtools/.project @@ -0,0 +1,23 @@ + + + SerialX-devtools + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SerialX-devtools/.settings/org.eclipse.core.resources.prefs b/SerialX-devtools/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/SerialX-devtools/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs b/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..2f5cc74 --- /dev/null +++ b/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs b/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml new file mode 100644 index 0000000..2140bc2 --- /dev/null +++ b/SerialX-devtools/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + devtools + 1.3.7 + + SerialX devtools + Tools for debugging... + + + + org.ugp.serialx + core + ${revision} + + + \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java similarity index 63% rename from SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java rename to SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index e19307c..a0f80d0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -1,14 +1,14 @@ -package org.ugp.serialx; +package org.ugp.serialx.devtools; import java.util.Arrays; - import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.TreeMap; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.devtools.converters.DebugParserRegistry; /** * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
@@ -26,11 +26,9 @@ public class SerializationDebugger implements DataConverter @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - synchronized (this) { - if (str.toLowerCase().startsWith(DEBUG_MARK)) - return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); - return CONTINUE; - } + if (str.toLowerCase().startsWith(DEBUG_MARK)) + return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); + return CONTINUE; } @Override @@ -72,8 +70,7 @@ public Object printDebugs(DebugParserRegistry myHomeRegistry, Object objToSerial } else if (args[99] instanceof Integer && (int) args[99] > 0) { - myHomeRegistry = myHomeRegistry.clone(); - myHomeRegistry.iterationStackTrace = new TreeMap<>(); + myHomeRegistry = myHomeRegistry.clone(false); } double t0 = System.nanoTime(); @@ -101,8 +98,7 @@ else if (args[99] instanceof Integer && (int) args[99] > 0) } else if (args[99] instanceof Integer && (int) args[99] > 0) { - myHomeRegistry = myHomeRegistry.clone(); - myHomeRegistry.iterationStackTrace = new TreeMap<>(); + myHomeRegistry = myHomeRegistry.clone(false); } double t0 = System.nanoTime(); @@ -228,7 +224,7 @@ else if (o instanceof Map) System.err.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); } } - + /** * Use this during converting/serializing! * @@ -252,149 +248,4 @@ public DebugWrapper(Object yourObject) obj = yourObject; } } - - /** - * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! - * - * @author PETO - * - * @since 1.3.5 - */ - public static class DebugParserRegistry extends ParserRegistry - { - /** - * - */ - private static final long serialVersionUID = 3445967263611388142L; - - protected Map iterationStackTrace = new TreeMap<>(); - - public DebugParserRegistry(ParserRegistry registry) - { - super(registry); - resetCache(registry.getParsingCache(), registry.getConverterCache()); - } - - @Override - public DebugParserRegistry clone() - { - DebugParserRegistry reg = new DebugParserRegistry(this); - reg.iterationStackTrace = this.iterationStackTrace; - return reg; - } - - @Override - public CharSequence toString(Object obj, Object... args) { - int iterationIndex = 0; - if (args.length > 99 && args[99] instanceof Integer) - { - iterationIndex = (int) args[99]; - args[99] = iterationIndex + 1; - } - - CharSequence str = null; - if (convertingCache != null) - for (int i = 0; i < convertingCache.length; i++) - { - DataParser parser = convertingCache[i]; - if (parser != null) - { - double t0 = System.nanoTime(); - str = ((DataConverter) parser).toString(this, obj, args); - double t = System.nanoTime(); - if (str != CONTINUE) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return str; - } - } - } - - for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (parser instanceof DataConverter) - { - double t0 = System.nanoTime(); - str = ((DataConverter) parser).toString(this, obj, args); - double t = System.nanoTime(); - if(str != CONTINUE) - { - if (convertingCache != null && i < convertingCache.length) - convertingCache[i] = parser; - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return str; - } - } - } - - LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); - return null; - } - - @Override - public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) - { - int iterationIndex = 0; - if (args.length > 99 && args[99] instanceof Integer) - { - iterationIndex = (int) args[99]; - args[99] = iterationIndex + 1; - } - - Object obj = null; - if (parsingCache != null) - for (int i = 0; i < parsingCache.length; i++) - { - DataParser parser = parsingCache[i]; - if (parser != null) - { - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != CONTINUE) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + toStringAndCls(obj)); - return obj; - } - } - } - - registryLoop: for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (ignore != null) - for (Class cls : ignore) - if (cls == parser.getClass()) - continue registryLoop; - - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != CONTINUE) - { - if (parsingCache != null && i < parsingCache.length) - parsingCache[i] = parser; - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + toStringAndCls(obj)); - return obj; - } - } - - if (returnAsStringIfNotFound) - return str; - - LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); - return null; - } - - /** - * @return Ordered map of registry iterations generated by using it during parsing or converting! - * - * @since 1.3.5 - */ - public Map getRegistryIterationStackTrace() - { - return iterationStackTrace; - } - } } \ No newline at end of file diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java new file mode 100644 index 0000000..2ad0472 --- /dev/null +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java @@ -0,0 +1,165 @@ +package org.ugp.serialx.devtools.converters; + +import java.util.Map; +import java.util.TreeMap; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.devtools.SerializationDebugger; + +/** + * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! + * + * @author PETO + * + * @since 1.3.5 + */ +public class DebugParserRegistry extends ParserRegistry +{ + private static final long serialVersionUID = 3445967263611388142L; + + protected Map iterationStackTrace = new TreeMap<>(); + + public DebugParserRegistry(ParserRegistry registry) + { + super(registry); + resetCache(registry.getParsingCache(), registry.getConverterCache()); + } + + @Override + public DebugParserRegistry clone() + { + return clone(true); + } + + /** + * @param copyStackTrace | If true, cloned object will share the same iterationStackTrace with original, otherwise it will get new empty one. + * + * @return Clone of this {@link DebugParserRegistry} + * + * @since 1.3.7 + */ + public DebugParserRegistry clone(boolean copyStackTrace) + { + DebugParserRegistry reg = new DebugParserRegistry(this); + if (copyStackTrace) + reg.iterationStackTrace = this.iterationStackTrace; + return reg; + } + + @Override + public CharSequence toString(Object obj, Object... args) { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + CharSequence str = null; + if (convertingCache != null) + for (int i = 0; i < convertingCache.length; i++) + { + DataParser parser = convertingCache[i]; + if (parser != null) + { + double t0 = System.nanoTime(); + str = ((DataConverter) parser).toString(this, obj, args); + double t = System.nanoTime(); + if (str != SerializationDebugger.CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return str; + } + } + } + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (parser instanceof DataConverter) + { + double t0 = System.nanoTime(); + str = ((DataConverter) parser).toString(this, obj, args); + double t = System.nanoTime(); + if(str != SerializationDebugger.CONTINUE) + { + if (convertingCache != null && i < convertingCache.length) + convertingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return str; + } + } + } + + LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + return null; + } + + @Override + public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) + { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + Object obj = null; + if (parsingCache != null) + for (int i = 0; i < parsingCache.length; i++) + { + DataParser parser = parsingCache[i]; + if (parser != null) + { + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } + } + } + + registryLoop: for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (ignore != null) + for (Class cls : ignore) + if (cls == parser.getClass()) + continue registryLoop; + + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } + } + + if (returnAsStringIfNotFound) + return str; + + LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + return null; + } + + /** + * @return Ordered map of registry iterations generated by using it during parsing or converting! + * + * @since 1.3.5 + */ + public Map getRegistryIterationStackTrace() + { + return iterationStackTrace; + } +} \ No newline at end of file diff --git a/SerialX-json/.settings/org.eclipse.core.resources.prefs b/SerialX-json/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/SerialX-json/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 9b6b1be..bf6b4db 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -3,19 +3,21 @@ org.ugp serialx - 1.3.7 + ${revision} + org.ugp.serialx json + 1.3.7 - SerialX-json + SerialX json SerialX Json support org.ugp.serialx core - 1.3.7 + ${revision} \ No newline at end of file diff --git a/SerialX-operators/.classpath b/SerialX-operators/.classpath new file mode 100644 index 0000000..002ad57 --- /dev/null +++ b/SerialX-operators/.classpath @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-operators/.project b/SerialX-operators/.project new file mode 100644 index 0000000..27a03a7 --- /dev/null +++ b/SerialX-operators/.project @@ -0,0 +1,23 @@ + + + SerialX-operators + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + diff --git a/SerialX-operators/.settings/org.eclipse.core.resources.prefs b/SerialX-operators/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..29abf99 --- /dev/null +++ b/SerialX-operators/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,6 @@ +eclipse.preferences.version=1 +encoding//src/main/java=UTF-8 +encoding//src/main/resources=UTF-8 +encoding//src/test/java=UTF-8 +encoding//src/test/resources=UTF-8 +encoding/=UTF-8 diff --git a/SerialX-operators/.settings/org.eclipse.jdt.core.prefs b/SerialX-operators/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..2f5cc74 --- /dev/null +++ b/SerialX-operators/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,8 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore +org.eclipse.jdt.core.compiler.release=disabled +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-operators/.settings/org.eclipse.m2e.core.prefs b/SerialX-operators/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..f897a7f --- /dev/null +++ b/SerialX-operators/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml new file mode 100644 index 0000000..f27574e --- /dev/null +++ b/SerialX-operators/pom.xml @@ -0,0 +1,23 @@ + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + operators + 1.3.7 + + SerialX operators + This modul contains basic operators contained in almost every programing language... + + + + org.ugp.serialx + core + ${revision} + + + \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java new file mode 100644 index 0000000..64c0c9f --- /dev/null +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java @@ -0,0 +1,69 @@ +package org.ugp.serialx.converters; + +import java.util.Arrays; + +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.operators.ArithmeticOperators; +import org.ugp.serialx.converters.operators.ComparisonOperators; +import org.ugp.serialx.converters.operators.ConditionalAssignmentOperators; +import org.ugp.serialx.converters.operators.LogicalOperators; +import org.ugp.serialx.converters.operators.NegationOperator; + +/** + * This class contains all operators that are provided by this module and it allows you to install it to your specific {@link ParserRegistry}! + * + * @see Operators#install(ParserRegistry) + * + * @since 1.3.7 + * + * @author PETO + */ +public class Operators { + + /** + * Array that contains all binary operators (operators that require 2 operands, one from left, one from right). This includes:
+ * {@link ConditionalAssignmentOperators}
+ * {@link LogicalOperators}
+ * {@link ComparisonOperators}
+ * {@link ArithmeticOperators}
+ * In given order! + * + * @since 1.3.7 + */ + public static final DataParser[] BINARY = { new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators() }; + + /** + * Array that contains all unary operators (operators that require only 1 operands, from left or right). This includes:
+ * {@link NegationOperator}
+ * In given order! + * + * @since 1.3.7 + */ + public static final DataParser[] UNARY = { new NegationOperator() }; + + /** + * @param registry | Registry to insert all operators provided by {@link Operators#BINARY} and {@link Operators#UNARY} into. This register is required to contains {@link StringConverter} and {@link BooleanConverter} in order for operators to be inserted in correct order and work in precedence they were meant to. + * + * @return The same registry with operators inserted! + * + * @since 1.3.7 + */ + public static ParserRegistry install(ParserRegistry registry) { + registry.addAllBefore(StringConverter.class, true, BINARY); + registry.addAllBefore(BooleanConverter.class, true, UNARY); + return registry; + } + + /** + * @param registry | Registry to remove all operators from! + * + * @return The same registry with no more operators! + * + * @since 1.3.7 + */ + public static ParserRegistry uninstall(ParserRegistry registry) { + registry.removeAll(Arrays.asList(BINARY)); + registry.removeAll(Arrays.asList(UNARY)); + return registry; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java rename to SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java rename to SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java rename to SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java similarity index 99% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java rename to SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index a0f8487..c8d4945 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -55,7 +55,7 @@ public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) } else if (opr.equals("||")) { - cof1 = cofs.get(index); + cof1 = cofs.get(index); if (cof1 instanceof String) cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); if (cof1.equals(true)) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java rename to SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java diff --git a/pom.xml b/pom.xml index c9a8d30..db0f207 100644 --- a/pom.xml +++ b/pom.xml @@ -3,12 +3,14 @@ org.ugp serialx - 1.3.7 + ${revision} pom SerialX-json SerialX-core + SerialX-devtools + SerialX-operators SerialX root @@ -37,21 +39,42 @@ https://github.com/SimplyProgrammer/ - - 1.8 - 1.8 + + 1.8 + 1.3.7 + + UTF-8 + ${java.version} + ${java.version} + serialx-${project.artifactId}-${project.version} + - org.apache.maven.plugins + org.apache.maven.plugins maven-compiler-plugin - 3.2 + 3.8.0 + - 1.8 - 1.8 + ${java.version} + ${java.version} + + eclipse + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.8.8 + + + org.eclipse.jdt + ecj + 3.25.0 + + From 9357c4f79030db5379edf762db50349d9ea10b66 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 26 Jun 2023 16:07:23 +0200 Subject: [PATCH 05/75] further modularization and bug fixes --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 04f470d..a81c963 100644 --- a/.gitignore +++ b/.gitignore @@ -33,5 +33,6 @@ npm-debug.log* bin/ tmp/ .metadata +.settings target/ From 3902a4b082cac354425eda529c4e908a7c18b0a4 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 26 Jun 2023 16:08:47 +0200 Subject: [PATCH 06/75] further modularization and bug fixes --- .settings/org.eclipse.core.resources.prefs | 2 -- .settings/org.eclipse.jdt.core.prefs | 8 -------- .settings/org.eclipse.m2e.core.prefs | 4 ---- SerialX-core/.settings/org.eclipse.core.resources.prefs | 6 ------ SerialX-core/.settings/org.eclipse.jdt.core.prefs | 8 -------- SerialX-core/.settings/org.eclipse.m2e.core.prefs | 4 ---- .../.settings/org.eclipse.core.resources.prefs | 6 ------ SerialX-devtools/.settings/org.eclipse.jdt.core.prefs | 8 -------- SerialX-devtools/.settings/org.eclipse.m2e.core.prefs | 4 ---- SerialX-json/.settings/org.eclipse.core.resources.prefs | 6 ------ SerialX-json/.settings/org.eclipse.jdt.core.prefs | 8 -------- SerialX-json/.settings/org.eclipse.m2e.core.prefs | 4 ---- .../.settings/org.eclipse.core.resources.prefs | 6 ------ SerialX-operators/.settings/org.eclipse.jdt.core.prefs | 8 -------- SerialX-operators/.settings/org.eclipse.m2e.core.prefs | 4 ---- 15 files changed, 86 deletions(-) delete mode 100644 .settings/org.eclipse.core.resources.prefs delete mode 100644 .settings/org.eclipse.jdt.core.prefs delete mode 100644 .settings/org.eclipse.m2e.core.prefs delete mode 100644 SerialX-core/.settings/org.eclipse.core.resources.prefs delete mode 100644 SerialX-core/.settings/org.eclipse.jdt.core.prefs delete mode 100644 SerialX-core/.settings/org.eclipse.m2e.core.prefs delete mode 100644 SerialX-devtools/.settings/org.eclipse.core.resources.prefs delete mode 100644 SerialX-devtools/.settings/org.eclipse.jdt.core.prefs delete mode 100644 SerialX-devtools/.settings/org.eclipse.m2e.core.prefs delete mode 100644 SerialX-json/.settings/org.eclipse.core.resources.prefs delete mode 100644 SerialX-json/.settings/org.eclipse.jdt.core.prefs delete mode 100644 SerialX-json/.settings/org.eclipse.m2e.core.prefs delete mode 100644 SerialX-operators/.settings/org.eclipse.core.resources.prefs delete mode 100644 SerialX-operators/.settings/org.eclipse.jdt.core.prefs delete mode 100644 SerialX-operators/.settings/org.eclipse.m2e.core.prefs diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 99f26c0..0000000 --- a/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,2 +0,0 @@ -eclipse.preferences.version=1 -encoding/=UTF-8 diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2f5cc74..0000000 --- a/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/SerialX-core/.settings/org.eclipse.core.resources.prefs b/SerialX-core/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/SerialX-core/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/SerialX-core/.settings/org.eclipse.jdt.core.prefs b/SerialX-core/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2f5cc74..0000000 --- a/SerialX-core/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-core/.settings/org.eclipse.m2e.core.prefs b/SerialX-core/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/SerialX-core/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/SerialX-devtools/.settings/org.eclipse.core.resources.prefs b/SerialX-devtools/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/SerialX-devtools/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs b/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2f5cc74..0000000 --- a/SerialX-devtools/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs b/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/SerialX-devtools/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/SerialX-json/.settings/org.eclipse.core.resources.prefs b/SerialX-json/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/SerialX-json/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/SerialX-json/.settings/org.eclipse.jdt.core.prefs b/SerialX-json/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2f5cc74..0000000 --- a/SerialX-json/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-json/.settings/org.eclipse.m2e.core.prefs b/SerialX-json/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/SerialX-json/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/SerialX-operators/.settings/org.eclipse.core.resources.prefs b/SerialX-operators/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index 29abf99..0000000 --- a/SerialX-operators/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,6 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding//src/test/java=UTF-8 -encoding//src/test/resources=UTF-8 -encoding/=UTF-8 diff --git a/SerialX-operators/.settings/org.eclipse.jdt.core.prefs b/SerialX-operators/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2f5cc74..0000000 --- a/SerialX-operators/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,8 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 -org.eclipse.jdt.core.compiler.compliance=1.8 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=1.8 diff --git a/SerialX-operators/.settings/org.eclipse.m2e.core.prefs b/SerialX-operators/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/SerialX-operators/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 From ced013115755c62b688b6932c9c9e2b6c1ece160 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 18 Jul 2023 22:43:32 +0200 Subject: [PATCH 07/75] ... --- .classpath | 9 - .gitignore | 2 + .project | 23 - SerialX-core/.classpath | 38 - SerialX-core/.project | 23 - .../java/org/ugp/serialx/GenericScope.java | 17 +- .../java/org/ugp/serialx/JussSerializer.java | 12 +- .../src/main/java/org/ugp/serialx/Scope.java | 3 +- .../main/java/org/ugp/serialx/Serializer.java | 783 +---------------- .../src/main/java/org/ugp/serialx/Utils.java | 806 ++++++++++++++++++ .../serialx/converters/ArrayConverter.java | 24 +- .../serialx/converters/BooleanConverter.java | 6 +- .../converters/CharacterConverter.java | 7 +- .../ugp/serialx/converters/DataParser.java | 1 - .../ugp/serialx/converters/NullConverter.java | 4 +- .../serialx/converters/NumberConverter.java | 109 ++- .../serialx/converters/ObjectConverter.java | 16 +- .../serialx/converters/OperationGroups.java | 2 +- .../serialx/converters/StringConverter.java | 4 +- .../serialx/converters/VariableConverter.java | 14 +- .../ugp/serialx/protocols/AutoProtocol.java | 3 +- .../UniversalObjectInstantiationProtocol.java | 4 +- SerialX-devtools/.classpath | 38 - SerialX-devtools/.project | 23 - .../devtools/SerializationDebugger.java | 8 +- SerialX-json/.classpath | 38 - SerialX-json/.project | 23 - .../org/ugp/serialx/json/JsonSerializer.java | 14 +- .../json/converters/JsonNumberConverter.java | 2 +- SerialX-juss/pom.xml | 15 + SerialX-operators/.classpath | 38 - SerialX-operators/.project | 23 - .../operators/ArithmeticOperators.java | 12 +- .../operators/ComparisonOperators.java | 2 +- .../ConditionalAssignmentOperators.java | 4 +- .../operators/LogicalOperators.java | 2 +- pom.xml | 4 +- 37 files changed, 974 insertions(+), 1182 deletions(-) delete mode 100644 .classpath delete mode 100644 .project delete mode 100644 SerialX-core/.classpath delete mode 100644 SerialX-core/.project create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/Utils.java delete mode 100644 SerialX-devtools/.classpath delete mode 100644 SerialX-devtools/.project delete mode 100644 SerialX-json/.classpath delete mode 100644 SerialX-json/.project create mode 100644 SerialX-juss/pom.xml delete mode 100644 SerialX-operators/.classpath delete mode 100644 SerialX-operators/.project diff --git a/.classpath b/.classpath deleted file mode 100644 index bd36355..0000000 --- a/.classpath +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/.gitignore b/.gitignore index a81c963..2957f58 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ npm-debug.log* bin/ tmp/ .metadata +.classpath .settings +.project target/ diff --git a/.project b/.project deleted file mode 100644 index fd37aa3..0000000 --- a/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - SerialXDev - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/SerialX-core/.classpath b/SerialX-core/.classpath deleted file mode 100644 index 002ad57..0000000 --- a/SerialX-core/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SerialX-core/.project b/SerialX-core/.project deleted file mode 100644 index 75fcc6c..0000000 --- a/SerialX-core/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - SerialX-core - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 9ad062b..bdb25df 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -1,5 +1,7 @@ package org.ugp.serialx; +import static org.ugp.serialx.Utils.Instantiate; + import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -14,6 +16,7 @@ import java.util.function.Function; import java.util.function.Predicate; +import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.ArrayConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.protocols.SerializationProtocol; @@ -146,7 +149,7 @@ public GenericScope clone() @SuppressWarnings("unchecked") public > S clone(Class typeOfClone) throws Exception { - S clone = Serializer.Instantiate(typeOfClone); + S clone = Instantiate(typeOfClone); clone.values = (List) toValList(); clone.variables = (Map) toVarMap(); clone.parent = getParent(); @@ -167,7 +170,7 @@ public > S clone(Class typeOfClone) throws if (getClass() == newType) return (S) this; - GenericScope clone = (GenericScope) Serializer.Instantiate(newType); + GenericScope clone = (GenericScope) Instantiate(newType); clone.values = (List) values(); clone.variables = (Map) variables(); clone.parent = getParent(); @@ -275,7 +278,7 @@ public V get(KeyT variableKey, V defaultValue) V obj = (V) variables().get(variableKey); if (obj == null) return (V) defaultValue; - return obj instanceof Serializer.NULL ? null : obj; + return obj instanceof NULL ? null : obj; } /** @@ -317,7 +320,7 @@ public boolean containsIndependentValue(ValT value) public V get(int valueIndex) { V obj = (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); - return obj instanceof Serializer.NULL ? null : obj; + return obj instanceof NULL ? null : obj; } /** @@ -524,7 +527,7 @@ public GenericScope transform(Function trans, boolean incl try { Object obj = ent.getValue(); - obj = obj instanceof Serializer.NULL ? null : obj; + obj = obj instanceof NULL ? null : obj; if (obj instanceof GenericScope && includeSubScopes) { GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); @@ -539,7 +542,7 @@ else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) try { - GenericScope clone = Serializer.Instantiate(getClass()); + GenericScope clone = Instantiate(getClass()); clone.values = fltVals; clone.variables = fltVars; clone.parent = getParent(); @@ -580,7 +583,7 @@ public List map(Function trans, boolean includeSubScopes) for (Object obj : this) try { - obj = obj instanceof Serializer.NULL ? null : obj; + obj = obj instanceof NULL ? null : obj; if (obj instanceof GenericScope && includeSubScopes) { GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java index 008607d..7cb815e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java @@ -1,5 +1,9 @@ package org.ugp.serialx; +import static org.ugp.serialx.Utils.Clone; +import static org.ugp.serialx.Utils.InvokeStaticFunc; +import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.converters.DataParser.VOID; import java.beans.IntrospectionException; @@ -21,6 +25,7 @@ import java.util.Map; import java.util.Map.Entry; +import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; @@ -38,6 +43,7 @@ * * @since 1.3.2 */ +//TODO: Separate to SerialX-juss together with parsers and stuff @SuppressWarnings("serial") public class JussSerializer extends Serializer implements ImportsProvider { @@ -483,7 +489,7 @@ else if (ch == '}' || ch == ']') else for (Map.Entry ent : parent.varEntrySet()) if (variables().get(ent.getKey()) == ent.getValue()) - variables().remove(ent.getKey()); + variables().remove(ent.getKey());//TODO: Prevent neccesity of scope parent inheritance. return (S) this; } @@ -695,7 +701,7 @@ public T cloneOf(String variableName , T defaultValue) T obj = get(variableName , defaultValue); if (obj == defaultValue) return defaultValue; - return Serializer.Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); } /** @@ -711,7 +717,7 @@ public T cloneOf(String variableName , T defaultValue) public T cloneOf(int valueIndex) { T obj = get(valueIndex); - return Serializer.Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index 6cadf3c..61c5839 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1,5 +1,6 @@ package org.ugp.serialx; +import static org.ugp.serialx.Utils.Instantiate; import static org.ugp.serialx.converters.DataParser.VOID; import java.beans.IntrospectionException; @@ -1100,7 +1101,7 @@ public static T intoNew(Class objCls, GenericScope fromScope, } } - return into(Serializer.Instantiate(objCls), fromScope, fieldNamesToUse); + return into(Instantiate(objCls), fromScope, fieldNamesToUse); } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 9bd75d3..ccae28e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -1,10 +1,12 @@ package org.ugp.serialx; -import static org.ugp.serialx.converters.DataParser.VOID; +import static org.ugp.serialx.Utils.Instantiate; +import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.Utils.post; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; -import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileNotFoundException; @@ -17,23 +19,17 @@ import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; -import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.function.Function; import org.ugp.serialx.converters.BooleanConverter; import org.ugp.serialx.converters.CharacterConverter; -import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; import org.ugp.serialx.converters.NullConverter; @@ -903,713 +899,6 @@ public T getParsed(String variableWithStringValue, Object... args) { return (T) getParsers().parse(getString(variableWithStringValue), args); } - - /** - * @param f | Source file. - * - * @return All lines from source file as string. - * @throws IOException - * - * @since 1.1.5 - */ - public static String LoadFileToString(File f) throws IOException - { - return LoadFileToString(f, 1); - } - - /** - * @param f | Source file. - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! - * - * @return Content of file as string. - * @throws IOException - * - * @since 1.2.0 - */ - public static String LoadFileToString(File f, int endlMode) throws IOException - { - return StreamToString(new FileReader(f), endlMode); - } - - /** - * @param input | Input stream to read to string! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.5 - */ - public static String StreamToString(InputStream input, int endlMode) throws IOException - { - return StreamToString(new InputStreamReader(input), endlMode); - } - - /** - * @param input | Input reader! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.2 - */ - public static String StreamToString(Reader input, int endlMode) throws IOException - { - String l; - StringBuilder sb = new StringBuilder(); - - BufferedReader r = new BufferedReader(input); - while ((l = r.readLine()) != null) - { - sb.append(l); - if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) - sb.append("\n"); - } - r.close(); - return sb.toString(); - } - - /** - * @param cls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.2.2 - */ - public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(null, cls, name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(obj, obj.getClass(), name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param cls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException - { - Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); - if (result != null) - return result; - result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); - if (result == null) - LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); - return result; - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param cls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param argClasses | Classes of args. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException - { - try - { - Method method = objCls.getMethod(name, argClasses); - Object resualt = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : resualt; - } - catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) - { - for (Method method : objCls.getMethods()) - if (method.getName().equals(name)) - try - { - Object resualt = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : resualt; - } - catch (IllegalArgumentException e) - {} - catch (SecurityException | IllegalAccessException ex) - { - ex.printStackTrace(); - } - } - return null; - } - - - //Syntactical analyzes and fast string utility: - - /** - * @param obj | Object to clone. - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! - * - * @since 1.2.2 - */ - public static T Clone(T obj) - { - return Clone(obj, DataParser.REGISTRY, new Object[] {}, new Scope()); - } - - /** - * @param obj | Object to clone. - * @param - * @param converterArgs | Argument for {@link DataConverter#objToString(Registry, Object, Object...)}! - * @param parserArgs | Arguments for {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)}! - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Clone(T obj, Registry parsersToUse, Object[] converterArgs, Object... parserArgs) - { - if (obj == null) - return obj; - else if (obj.getClass() == Byte.class) - return (T) new Byte((byte) obj); - else if (obj.getClass() == Short.class) - return (T) new Short((short) obj); - else if (obj.getClass() == Integer.class) - return (T) new Integer((int) obj); - else if (obj.getClass() == Long.class) - return (T) new Long((long) obj); - else if (obj.getClass() == Float.class) - return (T) new Float((float) obj); - else if (obj.getClass() == Double.class) - return (T) new Double((double) obj); - else if (obj.getClass() == Character.class) - return (T) new Character((char) obj); - else if (obj.getClass() == Boolean.class) - return (T) new Boolean((boolean) obj); - else if (obj.getClass() == String.class) - return (T) new String((String) obj); - else - { - ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); - - Object cln = NULL.toOopNull(parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs)); - if (cln != null && cln != VOID) - return (T) cln; - - if (obj instanceof Cloneable) - { - try - { - Method method = Object.class.getDeclaredMethod("clone"); - method.setAccessible(true); - return (T) method.invoke(obj); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); - return obj; - } - } - - /** - * @param cls | Class to instantiate. - * - * @return New blank instance of required class created by calling shortest public constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.2.2 - */ - public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException - { - return Instantiate(cls, true); - } - - /** - * @param cls | Class to instantiate. - * @param publicOnly | If true, only public constructors will be used to create the object! - * - * @return New blank instance of required class created by calling shortest constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException - { - try - { - Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); - if (!publicOnly) - cons.setAccessible(true); - return cons.newInstance(); - } - catch (Exception e) - { - try - { - Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); - if (cnstrs.length <= 0) - throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); - - for (int i = 1; i < cnstrs.length; i++) - { - if (!publicOnly) - cnstrs[0].setAccessible(true); - if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) - cnstrs[0] = cnstrs[i]; - } - - Object[] args = new Object[cnstrs[0].getParameterCount()]; - Class[] argTypes = cnstrs[0].getParameterTypes(); - for (int i = 0; i < cnstrs[0].getParameterCount(); i++) - { - if (argTypes[i] == byte.class) - args[i] = (byte) 0; - else if (argTypes[i] == short.class) - args[i] = (short) 0; - else if (argTypes[i] == int.class) - args[i] = 0; - else if (argTypes[i] == long.class) - args[i] = 0l; - else if ( argTypes[i] == float.class) - args[i] = 0.0f; - else if (argTypes[i] == double.class) - args[i] = 0.0; - else if (argTypes[i] == char.class) - args[i] = (char) 0; - else if (argTypes[i] == boolean.class) - args[i] = false; - else if (argTypes[i] == String.class) - args[i] = ""; - else - args[i] = null; - } - return (T) cnstrs[0].newInstance(args); - } - catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) - { - e2.printStackTrace(); - } - } - return null; - } - - /** - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.2.2 - */ - public static Class[] ToClasses(Object... objs) - { - return ToClasses(true, objs); - } - - /** - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.3.5 - */ - public static Class[] ToClasses(boolean unwrapp, Object... objs) - { - Class[] classes = new Class[objs.length]; - if (unwrapp) - { - for (int i = 0; i < classes.length; i++) - { - if (objs[i] == null) - classes[i] = Object.class; - else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) - classes[i] = byte.class; - else if (objs[i].getClass() == Short.class || objs[i] == Short.class) - classes[i] = short.class; - else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) - classes[i] = int.class; - else if (objs[i].getClass() == Long.class || objs[i] == Long.class) - classes[i] = long.class; - else if (objs[i].getClass() == Float.class || objs[i] == Float.class) - classes[i] = float.class; - else if (objs[i].getClass() == Double.class || objs[i] == Double.class) - classes[i] = double.class; - else if (objs[i].getClass() == Character.class || objs[i] == Character.class) - classes[i] = char.class; - else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) - classes[i] = boolean.class; - else if (objs[i] instanceof Class) - classes[i] = (Class) objs[i]; - else - classes[i] = objs[i].getClass(); - } - - return classes; - } - - for (int i = 0; i < classes.length; i++) - classes[i] = objs[i].getClass(); - return classes; - } - - /** - * @param ch | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; - * - * @since 1.3.2 - */ - public static StringBuilder multilpy(char ch, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(ch); - return sb; - } - - /** - * @param ch | String to multiply! - * @param str | Count of multiplication! - * - * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; - * - * @since 1.3.0 - */ - public static StringBuilder multilpy(CharSequence str, int times) - { - StringBuilder sb = new StringBuilder(str); - while (times-- > 1) - sb.append(str); - return sb; - } - - /** - * @param s | String to split and check some syntax. - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters. If there is more than one splitter in row, it will be taken as one whole! - * - * @since 1.0.0 - */ - public static String[] splitValues(String s, char... splitter) - { - return splitValues(s, 0, true, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! - * - * @since 1.3.0 - */ - public static String[] splitValues(String s, int limit, boolean splitAfterSingleCharOnly, char... splitter) - { - return splitValues(s, limit, splitAfterSingleCharOnly, new char[0], splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! - * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! - * - * @since 1.3.5 - */ - public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) - { - if (splitter.length <= 0 || limit == 1) - return new String[] {s}; -// -// if (isOneOf(s.charAt(0), splitter)) -// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); - - List result = new ArrayList<>(); - - int brackets = 0, quote = 0, lastIndex = 0; - for (int i = 0, count = 1, len = s.length(), oldCh = splitter[0]; i < len && (limit <= 0 || count < limit); i++) - { - char ch = s.charAt(i); - if (ch == '"') - quote++; - - if (quote % 2 == 0) - { - if (isOneOf(ch, splitBreaks)) - { - brackets = quote = 0; - break; - } - - if (brackets == 0 && oldCh != ch && isOneOf(ch, splitter) && (oneOrMore || (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) - { - result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i).trim()); - count++; - } - else if (ch == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + s); - } - } - oldCh = ch; - } - - if (brackets > 0) - throw new IllegalArgumentException("Unclosed brackets in: " + s); - else if (quote % 2 != 0) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); - else - { - result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, s.length()).trim()); - } - - return result.toArray(new String[0]); - } - - /** - * @param s | CharSequence to search! - * @param oneOf | Characters to find! - * - * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, char... oneOf) - { - return indexOfNotInObj(s, true, oneOf); - } - - /** - * @param s | CharSequence to search! - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param oneOf | Characters to find! - * - * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.5 - */ - public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... oneOf) - { - int found = -1; - for (int i = 0, brackets = 0, quote = 0, len = s.length(); i < len; i++) - { - char ch = s.charAt(i); - if (ch == '"') - quote++; - - if (quote % 2 == 0) - { - if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) - { - found = i; - if (firstIndex) - return found; - } - else if (ch == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); - } - } - } - return found; - } - - /** - * @param s | CharSequence to search! - * @param sequenceToFind | CharSequence to find! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind) - { - return indexOfNotInObj(s, sequenceToFind, true); - } - - /** - * @param s | CharSequence to search! - * @param sequenceToFind | CharSequence to find! - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.5 - */ - public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, boolean firstIndex) - { - int found = -1; - for (int i = 0, brackets = 0, quote = 0, match = 0, len = s.length(), lenToFind = sequenceToFind.length(); i < len; i++) - { - char ch = s.charAt(i); - if (ch == '"') - quote++; - - if (quote % 2 == 0) - { - if (brackets == 0 && ch == sequenceToFind.charAt(match++)) - { - if (match == lenToFind) - { - found = i - match + 1; - if (firstIndex) - return found; - match = 0; - } - } - else if (ch == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); - } - else - match = 0; - } - } - return found; - } - - /** - * @param str | String to do replacements in! - * @param target | Target to replace! - * @param replacement | Replacement for target! - * - * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! - * - * @since 1.2.0 - */ - public static String fastReplace(String str, String target, CharSequence replacement) - { - int targetLength = target.length(); - if (targetLength == 0) - return str; - - int i1 = 0, i2 = str.indexOf(target); - if (i2 < 0) - return str; - - StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2); - do - { - sb.append(str, i1, i2).append(replacement); - i1 = i2 + targetLength; - i2 = str.indexOf(target, i1); - } while (i2 > 0); - - return sb.append(str, i1, str.length()).toString(); - } - - /** - * @param ch | Char to compare! - * @param chars | Chars to match! - * - * @return True if inserted char is any of inserted chars! - * - * @since 1.3.0 - */ - public static boolean isOneOf(int ch, char... chars) - { - if (chars.length > 0) - { - for (int i = 0, len = chars.length; i < len; i++) - if (chars[i] == ch) - return true; - } - return false; - } - - /** - * @return {@link String#contains(CharSequence)} for char sequence! - * - * @since 1.3.0 - */ - public static boolean contains(CharSequence str, char... oneOf) - { - for (int i = 0, len = str.length(); i < len; i++) - if (isOneOf(str.charAt(i), oneOf)) - return true; - return false; - } - - /** - * @param str | String to display! - * @param pos | Position to display! - * - * @return String with displayed position! - * Use for debugging or error printing! - * - * @since 1.3.2 - */ - public static String showPosInString(CharSequence str, int pos) - { - return str + "\n" + multilpy(' ', pos) + "^"; - } /** * @param obj | Object to map the serializer variables into! @@ -1829,68 +1118,4 @@ public static Serializer from(Serializer newInstance, Object fromObj, String... newInstance.addAll(Scope.from(fromObj, fieldNamesToUse)); return newInstance; } - - /** - * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! - * - * @param serializer | Serializer to post. - * @param conn | Http connection to use! - * - * @throws IOException if posting failed! - * - * @since 1.3.5 - */ - public static void post(Serializer serializer, HttpURLConnection conn) throws IOException - { - StringBuilder postData = new StringBuilder(); - for (Map.Entry param : serializer.varEntrySet()) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); - } - - for (Object param : serializer) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); - } - - byte[] postDataBytes = postData.toString().getBytes("UTF-8"); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); - conn.setDoOutput(true); - conn.getOutputStream().write(postDataBytes); - } - - /** - * This is a "dummy" class that {@link Serializer} uses internally as an OOP programmatic interpretation of null. In otherwise this is wrapper object for null. - * Note: You should not be able to come in contact with this during serialization and loading, if you did then you most likely encountered and bug and you should report it! - * - * @author PETO - * - * @since 1.2.2 - */ - public static final class NULL - { - public static Object toOopNull(Object obj) - { - return obj == null ? new NULL() : obj; - } - - @Override - public boolean equals(Object obj) - { - return obj == null || obj instanceof NULL; - } - - @Override - public String toString() - { - return "null"; - } - } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java new file mode 100644 index 0000000..a9b8d48 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -0,0 +1,806 @@ +package org.ugp.serialx; + +import static org.ugp.serialx.converters.DataParser.VOID; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.protocols.SerializationProtocol; + + +public class Utils { + private Utils() {} + + /** + * @param f | Source file. + * + * @return All lines from source file as string. + * @throws IOException + * + * @since 1.1.5 + */ + public static String LoadFileToString(File f) throws IOException + { + return LoadFileToString(f, 1); + } + + /** + * @param f | Source file. + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Content of file as string. + * @throws IOException + * + * @since 1.2.0 + */ + public static String LoadFileToString(File f, int endlMode) throws IOException + { + return StreamToString(new FileReader(f), endlMode); + } + + /** + * @param input | Input stream to read to string! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.5 + */ + public static String StreamToString(InputStream input, int endlMode) throws IOException + { + return StreamToString(new InputStreamReader(input), endlMode); + } + + /** + * @param input | Input reader! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.2 + */ + public static String StreamToString(Reader input, int endlMode) throws IOException + { + String l; + StringBuilder sb = new StringBuilder(); + + BufferedReader r = new BufferedReader(input); + while ((l = r.readLine()) != null) + { + sb.append(l); + if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) + sb.append("\n"); + } + r.close(); + return sb.toString(); + } + + /** + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.2.2 + */ + public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(null, cls, name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(obj, obj.getClass(), name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException + { + Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); + if (result != null) + return result; + result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); + if (result == null) + LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); + return result; + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param argClasses | Classes of args. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException + { + try + { + Method method = objCls.getMethod(name, argClasses); + Object resualt = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : resualt; + } + catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) + { + for (Method method : objCls.getMethods()) + if (method.getName().equals(name)) + try + { + Object resualt = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : resualt; + } + catch (IllegalArgumentException e) + {} + catch (SecurityException | IllegalAccessException ex) + { + ex.printStackTrace(); + } + } + return null; + } + + + //Syntactical analyzes and fast string utility: + + /** + * @param obj | Object to clone. + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.2.2 + */ + public static T Clone(T obj) + { + return Clone(obj, DataParser.REGISTRY, new Object[] {}, new Scope()); + } + + /** + * @param obj | Object to clone. + * @param + * @param converterArgs | Argument for {@link DataConverter#objToString(Registry, Object, Object...)}! + * @param parserArgs | Arguments for {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)}! + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Clone(T obj, Registry parsersToUse, Object[] converterArgs, Object... parserArgs) + { + if (obj == null) + return obj; + else if (obj.getClass() == Byte.class) + return (T) new Byte((byte) obj); + else if (obj.getClass() == Short.class) + return (T) new Short((short) obj); + else if (obj.getClass() == Integer.class) + return (T) new Integer((int) obj); + else if (obj.getClass() == Long.class) + return (T) new Long((long) obj); + else if (obj.getClass() == Float.class) + return (T) new Float((float) obj); + else if (obj.getClass() == Double.class) + return (T) new Double((double) obj); + else if (obj.getClass() == Character.class) + return (T) new Character((char) obj); + else if (obj.getClass() == Boolean.class) + return (T) new Boolean((boolean) obj); + else if (obj.getClass() == String.class) + return (T) new String((String) obj); + else + { + ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); + + Object cln = NULL.toOopNull(parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs)); + if (cln != null && cln != VOID) + return (T) cln; + + if (obj instanceof Cloneable) + { + try + { + Method method = Object.class.getDeclaredMethod("clone"); + method.setAccessible(true); + return (T) method.invoke(obj); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); + return obj; + } + } + + /** + * @param cls | Class to instantiate. + * + * @return New blank instance of required class created by calling shortest public constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.2.2 + */ + public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException + { + return Instantiate(cls, true); + } + + /** + * @param cls | Class to instantiate. + * @param publicOnly | If true, only public constructors will be used to create the object! + * + * @return New blank instance of required class created by calling shortest constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException + { + try + { + Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); + if (!publicOnly) + cons.setAccessible(true); + return cons.newInstance(); + } + catch (Exception e) + { + try + { + Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); + if (cnstrs.length <= 0) + throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); + + for (int i = 1; i < cnstrs.length; i++) + { + if (!publicOnly) + cnstrs[0].setAccessible(true); + if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) + cnstrs[0] = cnstrs[i]; + } + + Object[] args = new Object[cnstrs[0].getParameterCount()]; + Class[] argTypes = cnstrs[0].getParameterTypes(); + for (int i = 0; i < cnstrs[0].getParameterCount(); i++) + { + if (argTypes[i] == byte.class) + args[i] = (byte) 0; + else if (argTypes[i] == short.class) + args[i] = (short) 0; + else if (argTypes[i] == int.class) + args[i] = 0; + else if (argTypes[i] == long.class) + args[i] = 0l; + else if ( argTypes[i] == float.class) + args[i] = 0.0f; + else if (argTypes[i] == double.class) + args[i] = 0.0; + else if (argTypes[i] == char.class) + args[i] = (char) 0; + else if (argTypes[i] == boolean.class) + args[i] = false; + else if (argTypes[i] == String.class) + args[i] = ""; + else + args[i] = null; + } + return (T) cnstrs[0].newInstance(args); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) + { + e2.printStackTrace(); + } + } + return null; + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.2.2 + */ + public static Class[] ToClasses(Object... objs) + { + return ToClasses(true, objs); + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.3.5 + */ + public static Class[] ToClasses(boolean unwrapp, Object... objs) + { + Class[] classes = new Class[objs.length]; + if (unwrapp) + { + for (int i = 0; i < classes.length; i++) + { + if (objs[i] == null) + classes[i] = Object.class; + else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) + classes[i] = byte.class; + else if (objs[i].getClass() == Short.class || objs[i] == Short.class) + classes[i] = short.class; + else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) + classes[i] = int.class; + else if (objs[i].getClass() == Long.class || objs[i] == Long.class) + classes[i] = long.class; + else if (objs[i].getClass() == Float.class || objs[i] == Float.class) + classes[i] = float.class; + else if (objs[i].getClass() == Double.class || objs[i] == Double.class) + classes[i] = double.class; + else if (objs[i].getClass() == Character.class || objs[i] == Character.class) + classes[i] = char.class; + else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) + classes[i] = boolean.class; + else if (objs[i] instanceof Class) + classes[i] = (Class) objs[i]; + else + classes[i] = objs[i].getClass(); + } + + return classes; + } + + for (int i = 0; i < classes.length; i++) + classes[i] = objs[i].getClass(); + return classes; + } + + /** + * @param ch | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; + * + * @since 1.3.2 + */ + public static StringBuilder multilpy(char ch, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(ch); + return sb; + } + + /** + * @param ch | String to multiply! + * @param str | Count of multiplication! + * + * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; + * + * @since 1.3.0 + */ + public static StringBuilder multilpy(CharSequence str, int times) + { + StringBuilder sb = new StringBuilder(str); + while (times-- > 1) + sb.append(str); + return sb; + } + + /** + * @param s | String to split and check some syntax. + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.0.0 + */ + public static String[] splitValues(String s, char... splitter) + { + return splitValues(s, 0, true, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.3.0 + */ + public static String[] splitValues(String s, int limit, boolean splitAfterSingleCharOnly, char... splitter) + { + return splitValues(s, limit, splitAfterSingleCharOnly, new char[0], splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * + * @since 1.3.5 + */ + public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) + { + if (splitter.length <= 0 || limit == 1) + return new String[] {s}; +// +// if (isOneOf(s.charAt(0), splitter)) +// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); + + List result = new ArrayList<>(); + + int brackets = 0, quote = 0, lastIndex = 0; + for (int i = 0, count = 1, len = s.length(), oldCh = splitter[0]; i < len && (limit <= 0 || count < limit); i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (isOneOf(ch, splitBreaks)) + { + brackets = quote = 0; + break; + } + + if (brackets == 0 && oldCh != ch && isOneOf(ch, splitter) && (oneOrMore || (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i).trim()); + count++; + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + s); + } + } + oldCh = ch; + } + + if (brackets > 0) + throw new IllegalArgumentException("Unclosed brackets in: " + s); + else if (quote % 2 != 0) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + else + { + result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, s.length()).trim()); + } + + return result.toArray(new String[0]); + } + + /** + * @param s | CharSequence to search! + * @param oneOf | Characters to find! + * + * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, char... oneOf) + { + return indexOfNotInObj(s, true, oneOf); + } + + /** + * @param s | CharSequence to search! + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param oneOf | Characters to find! + * + * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 + */ + public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... oneOf) + { + int found = -1; + for (int i = 0, brackets = 0, quote = 0, len = s.length(); i < len; i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) + { + found = i; + if (firstIndex) + return found; + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); + } + } + } + return found; + } + + /** + * @param s | CharSequence to search! + * @param sequenceToFind | CharSequence to find! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind) + { + return indexOfNotInObj(s, sequenceToFind, true); + } + + /** + * @param s | CharSequence to search! + * @param sequenceToFind | CharSequence to find! + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, boolean firstIndex) + { + int found = -1; + for (int i = 0, brackets = 0, quote = 0, match = 0, len = s.length(), lenToFind = sequenceToFind.length(); i < len; i++) + { + char ch = s.charAt(i); + if (ch == '"') + quote++; + + if (quote % 2 == 0) + { + if (brackets == 0 && ch == sequenceToFind.charAt(match++)) + { + if (match == lenToFind) + { + found = i - match + 1; + if (firstIndex) + return found; + match = 0; + } + } + else if (ch == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); + } + else + match = 0; + } + } + return found; + } + + /** + * @param str | String to do replacements in! + * @param target | Target to replace! + * @param replacement | Replacement for target! + * + * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! + * + * @since 1.2.0 + */ + public static String fastReplace(String str, String target, CharSequence replacement) + { + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, str.length()).toString(); + } + + /** + * @param ch | Char to compare! + * @param chars | Chars to match! + * + * @return True if inserted char is any of inserted chars! + * + * @since 1.3.0 + */ + public static boolean isOneOf(int ch, char... chars) + { + if (chars.length > 0) + { + for (int i = 0, len = chars.length; i < len; i++) + if (chars[i] == ch) + return true; + } + return false; + } + + /** + * @return {@link String#contains(CharSequence)} for char sequence! + * + * @since 1.3.0 + */ + public static boolean contains(CharSequence str, char... oneOf) + { + if (oneOf.length == 1) + for (int i = 0, len = str.length(); i < len; i++) + if (str.charAt(i) == oneOf[0]) + return true; + + for (int i = 0, len = str.length(); i < len; i++) + if (isOneOf(str.charAt(i), oneOf)) + return true; + return false; + } + + /** + * @param str | String to display! + * @param pos | Position to display! + * + * @return String with displayed position! + * Use for debugging or error printing! + * + * @since 1.3.2 + */ + public static String showPosInString(CharSequence str, int pos) + { + return str + "\n" + multilpy(' ', pos) + "^"; + } + + /** + * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! + * + * @param serializer | Serializer to post. + * @param conn | Http connection to use! + * + * @throws IOException if posting failed! + * + * @since 1.3.5 + */ + public static void post(Serializer serializer, HttpURLConnection conn) throws IOException + { + StringBuilder postData = new StringBuilder(); + for (Map.Entry param : serializer.varEntrySet()) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); + } + + for (Object param : serializer) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); + } + + byte[] postDataBytes = postData.toString().getBytes("UTF-8"); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); + conn.setDoOutput(true); + conn.getOutputStream().write(postDataBytes); + } + + /** + * This is a "dummy" class that {@link Serializer} uses internally as an OOP programmatic interpretation of null. In otherwise this is wrapper object for null. + * Note: You should not be able to come in contact with this during serialization and loading, if you did then you most likely encountered and bug and you should report it! + * + * @author PETO + * + * @since 1.2.2 + */ + public static final class NULL + { + public static Object toOopNull(Object obj) + { + return obj == null ? new NULL() : obj; + } + + @Override + public boolean equals(Object obj) + { + return obj == null || obj instanceof NULL; + } + + @Override + public String toString() + { + return "null"; + } + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java index ab77cc0..45e756a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java @@ -1,12 +1,14 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.ToClasses; -import static org.ugp.serialx.Serializer.indexOfNotInObj; -import static org.ugp.serialx.Serializer.splitValues; +import static org.ugp.serialx.Utils.ToClasses; +import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.splitValues; import java.lang.reflect.Array; import java.util.Arrays; +import org.ugp.serialx.converters.imports.ImportsProvider; + /** * This converter is capable of converting primitive arrays. * Its case sensitive! @@ -99,10 +101,11 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. if (args.length > 2) args[2] = index + 1; + Object[] elms = fromAmbiguous(obj); StringBuilder sb = new StringBuilder(); - for (int i = 0, length = Array.getLength(obj), sizeEndl = 10000; i < length; i++) + for (int i = 0, length = elms.length, sizeEndl = 10000; i < length; i++) { - CharSequence str = myHomeRegistry.toString(Array.get(obj, i), args); + CharSequence str = myHomeRegistry.toString(elms[i], args); char ch = str.charAt(0); if (ch == '{' || ch == '[') sb.append("("+str+")"); @@ -182,7 +185,7 @@ public static Object[] mergeArrays(Object arr1, Object arr2) /** * @param array | Object that might be array! * - * @return Object transformed in to primitive array! + * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! * * @throws IllegalArgumentException if the specified object is not an array! * @@ -190,9 +193,12 @@ public static Object[] mergeArrays(Object arr1, Object arr2) */ public static Object[] fromAmbiguous(Object array) { - int len1 = Array.getLength(array); - Object[] arr = new Object[len1]; - for (int i = 0; i < len1; i++) + if (array instanceof Object[]) + return (Object[]) array; + + int len = Array.getLength(array); + Object[] arr = new Object[len]; + for (int i = 0; i < len; i++) arr[i] = Array.get(array, i); return arr; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index 094c4be..871a2c4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -54,11 +54,11 @@ public BooleanConverter(boolean shorten) } @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { - if (arg.equalsIgnoreCase("t") || arg.equalsIgnoreCase("true")) + if (arg.equalsIgnoreCase("T") || arg.equalsIgnoreCase("true")) return new Boolean(true); - else if (arg.equalsIgnoreCase("f") || arg.equalsIgnoreCase("false")) + if (arg.equalsIgnoreCase("F") || arg.equalsIgnoreCase("false")) return new Boolean(false); return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java index 90c775b..3db9a41 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.fastReplace; +import static org.ugp.serialx.Utils.fastReplace; /** * This converter is capable of converting {@link Character}. @@ -41,10 +41,9 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) if (str.length() > 1 && str.charAt(0) == '\'' && str.charAt(str.length()-1) == '\'') try { - if (str.equals("''")) + if (str.equals("''")) // TODO: str.length() == 2 + mby cache len return new Character(' '); - else - return new Character((char) Integer.parseInt(str = fastReplace(str, "'", ""))); + return new Character((char) Integer.parseInt(str = fastReplace(str, "'", ""))); } catch (Exception e) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index d50616c..1eee489 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -41,7 +41,6 @@ public interface DataParser * * @since 1.3.0 */ - //TODO ParserRegistry public static final ParserRegistry REGISTRY = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index ce04a67..1d772b3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import org.ugp.serialx.Serializer.NULL; +import org.ugp.serialx.Utils.NULL; /** * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. @@ -40,7 +40,7 @@ public Object parse(ParserRegistry registry, String str, Object... args) { if (str.equalsIgnoreCase("null")) return null; - else if (str.equalsIgnoreCase("void")) + if (str.equalsIgnoreCase("void")) return VOID; return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index dc69f63..68b0d6c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.contains; -import static org.ugp.serialx.Serializer.fastReplace; +import static org.ugp.serialx.Utils.contains; +import static org.ugp.serialx.Utils.fastReplace; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; @@ -80,8 +80,11 @@ public class NumberConverter implements DataConverter * Set this on null and decimal numbers will not be formated! Do this when you need accuracy! * * @serial 1.1.0 (moved to {@link NumberConverter} since 1.3.0) + * + * @deprecated DO NOT USE! Override {@link NumberConverter#format(Object)} and write your format logic there instead! */ - protected DecimalFormat decimalFormatter = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US)); + @Deprecated + public static DecimalFormat decimalFormatter = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US)); @Override public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) @@ -91,43 +94,42 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) char ch = arg.charAt(0); if (ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9')) { - arg = formatNum(arg.toLowerCase()); - if (arg.equals(".")) + arg = normFormatNum(arg.toLowerCase()); + ch = arg.charAt(arg.length()-1); //ch = last char + + if (ch == '.') return CONTINUE; - if (contains(arg, '.') || (!arg.startsWith("0x") && arg.endsWith("f") || arg.endsWith("d"))) + if (contains(arg, '.') || (!arg.startsWith("0x") && ch == 'f' || ch == 'd')) { - if (arg.endsWith("f")) + if (ch == 'f') return new Float(fastReplace(arg, "f", "")); - else - return new Double(fastReplace(arg, "d", "")); + return new Double(fastReplace(arg, "d", "")); + } + + try + { + // TODO: Use decode method instead of this mess if possible... + if (ch == 'l') + return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + if (ch == 's') + return new Short(Short.parseShort(fastReplace(fastReplace(fastReplace(arg, "s", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + if (ch == 'y') + return new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10)); + return new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + } + catch (NumberFormatException e) + { + if (arg.matches("[0-9.]+")) + try + { + return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); + } + catch (NumberFormatException e2) + { + LogProvider.instance.logErr("Number " + arg + " is too big for its datatype! Try to change its datatype to double (suffix D)!", e2); + return null; + } } - else - try - { - Number integer; - if (arg.endsWith("l")) - integer = new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - else if (arg.endsWith("s")) - integer = new Short(Short.parseShort(fastReplace(fastReplace(fastReplace(arg, "s", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - else if (arg.endsWith("y")) - integer = new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10)); - else - integer = new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - return integer; - } - catch (NumberFormatException e) - { - if (arg.matches("[0-9.]+")) - try - { - return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - } - catch (NumberFormatException e2) - { - LogProvider.instance.logErr("Number " + arg + " is too big for its datatype! Try to change its datatype to double (suffix D)!", e2); - return null; - } - } } } return CONTINUE; @@ -138,17 +140,17 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. { if (obj instanceof Number) { - String str = decimalFormatter != null ? decimalFormatter.format(obj) : obj.toString(); - if (!contains(str, '.') && obj instanceof Double) - str += "D"; + StringBuilder str = new StringBuilder(format((Number) obj)); + if (obj instanceof Double && !contains(str, '.')) + str.append('D'); else if (obj instanceof Float) - str += "F"; + str.append('F'); else if (obj instanceof Long) - str += "L"; - if (obj instanceof Short) - str += "S"; + str.append('L'); + else if (obj instanceof Short) + str.append('S'); else if (obj instanceof Byte) - str += "Y"; + str.append('Y'); return str; } return CONTINUE; @@ -161,22 +163,15 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob } /** - * @return {@link DecimalFormat} to format decimal numbers (double, float) during serialization or null if there is none! - * Value of {@link NumberConverter#decimalFormatter} + * @param num | Number to format before converting it to string by this converter! * - * @since 1.3.7 - */ - public DecimalFormat getDecimalFormatter() { - return decimalFormatter; - } - - /** - * @param decimalFormatter | New {@link DecimalFormat} to set for formating decimal numbers (double, float)! + * @return Number formated to string! * * @since 1.3.7 */ - public void setDecimalFormatter(DecimalFormat decimalFormatter) { - this.decimalFormatter = decimalFormatter; + public String format(Number num) + { + return num.toString(); } /** @@ -186,7 +181,7 @@ public void setDecimalFormatter(DecimalFormat decimalFormatter) { * * @since 1.3.0 */ - public static String formatNum(String num) + public static String normFormatNum(String num) { if (num.length() > 2) for (boolean minus = num.startsWith("+-") || num.startsWith("-+"); minus || num.startsWith("++") || num.startsWith("--"); minus = num.startsWith("+-") || num.startsWith("-+")) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java index 02c0f90..021a6b0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java @@ -1,9 +1,10 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.InvokeStaticFunc; -import static org.ugp.serialx.Serializer.indexOfNotInObj; -import static org.ugp.serialx.Serializer.isOneOf; -import static org.ugp.serialx.Serializer.splitValues; +import static org.ugp.serialx.Utils.Instantiate; +import static org.ugp.serialx.Utils.InvokeStaticFunc; +import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.isOneOf; +import static org.ugp.serialx.Utils.splitValues; import java.io.IOException; import java.io.Serializable; @@ -83,7 +84,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile if (str.length() > 0 && ((hasOp = (ch = str.charAt(0)) == '{' || ch == '[') && (hasCls = (ch = str.charAt(str.length()-1)) == '}' || ch == ']') /*|| containsNotInObj(str, ' ')*/ || (objectClass = getProtocolExprClass(str, compilerArgs)) != null)) { - if (objectClass != null) + if (objectClass != null) //TODO: Preferably separate this to ProtocolConverter { if (objectClass == IsSelectorScope.class) { @@ -121,7 +122,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile try { compilerArgs[4] = oldObjectClass; - return clsAttr[1].equals("class") ? objectClass : clsAttr[1].equals("new") ? Serializer.Instantiate(objectClass) : objectClass.getField(clsAttr[1]).get(null); + return clsAttr[1].equals("class") ? objectClass : clsAttr[1].equals("new") ? Instantiate(objectClass) : objectClass.getField(clsAttr[1]).get(null); } catch (NoSuchFieldException e) { @@ -208,6 +209,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile { compilerArgs = compilerArgs.clone(); compilerArgs[0] = false; + //TODO: Prevent neccesity of scope parent inheritance. return ((Serializer) scope.inheritParent()).LoadFrom(new StringReader(str), compilerArgs); } @@ -307,7 +309,7 @@ else if (args.length > 0 && args[0] instanceof Serializer) throw new RuntimeException(e); } } - else + else //TODO: Preferably separate this to ProtocolConverter { if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java index 161f254..8374a40 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.isOneOf; +import static org.ugp.serialx.Utils.isOneOf; import java.util.Arrays; import java.util.HashMap; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 206dd48..33984bb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.contains; -import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Utils.contains; +import static org.ugp.serialx.Utils.indexOfNotInObj; import org.ugp.serialx.Registry; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java index 6937c7b..7d51f0b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java @@ -1,10 +1,10 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Serializer.Clone; -import static org.ugp.serialx.Serializer.contains; -import static org.ugp.serialx.Serializer.fastReplace; -import static org.ugp.serialx.Serializer.multilpy; -import static org.ugp.serialx.Serializer.splitValues; +import static org.ugp.serialx.Utils.Clone; +import static org.ugp.serialx.Utils.contains; +import static org.ugp.serialx.Utils.fastReplace; +import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.Utils.splitValues; import java.util.AbstractMap; import java.util.Arrays; @@ -14,7 +14,7 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer.NULL; +import org.ugp.serialx.Utils.NULL; /** * This converter is capable of converting {@link Map.Entry} and reading variables from {@link Scope} via "$"! @@ -108,7 +108,7 @@ else if (arg.charAt(0) == '$' && !contains(arg, ' ', '+', '-', '*', '/', '%', '> if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1) { Object[] tree = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.'); - GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(tree, 0, tree.length-1)); + GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(tree, 0, tree.length-1)); //TODO: Prevent neccesity of scope parent inheritance. obj = sc == null ? null : sc.variables().get(tree[tree.length-1]); /*if (sc == null || !sc.containsVariable(tree[tree.length-1])) LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java index 2246d6d..cb717f7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java @@ -8,6 +8,7 @@ import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; +import org.ugp.serialx.Utils; /** * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! @@ -127,7 +128,7 @@ public AutoProtocol(Class applicableFor, boolean useScope, List objectClass) throws Exception { - return Serializer.Instantiate(objectClass); + return Utils.Instantiate(objectClass); } @Override diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java index 414c37f..c058b89 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java @@ -4,7 +4,7 @@ import java.util.Arrays; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Serializer; +import org.ugp.serialx.Utils; /** * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! @@ -30,7 +30,7 @@ public T unserialize(Class objectClass, Object... args) throws Exce { try { - return objectClass.getConstructor(Serializer.ToClasses(args)).newInstance(args); + return objectClass.getConstructor(Utils.ToClasses(args)).newInstance(args); } catch (Exception e0) { diff --git a/SerialX-devtools/.classpath b/SerialX-devtools/.classpath deleted file mode 100644 index 002ad57..0000000 --- a/SerialX-devtools/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SerialX-devtools/.project b/SerialX-devtools/.project deleted file mode 100644 index b5f340d..0000000 --- a/SerialX-devtools/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - SerialX-devtools - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index a0f80d0..0476abd 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -1,5 +1,7 @@ package org.ugp.serialx.devtools; +import static org.ugp.serialx.Utils.multilpy; + import java.util.Arrays; import java.util.List; import java.util.Map; @@ -194,13 +196,13 @@ public static void print(String text, List objs, int tabs) for (int i = 0, i2 = 0; i < objs.size(); i++) { Object o = objs.get(i); - String strTbs = Serializer.multilpy('\t', tabs).toString(); + String strTbs = multilpy('\t', tabs).toString(); if (o instanceof List) print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); else if (o instanceof Map) print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); else - System.err.println(Serializer.multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); + System.err.println(multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); } } @@ -215,7 +217,7 @@ public static void print(String text, Map map, int tabs) for (Entry entry : map.entrySet()) { Object o = entry.getValue(); - String strTbs = Serializer.multilpy('\t', tabs).toString(); + String strTbs = multilpy('\t', tabs).toString(); if (o instanceof List) print(strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); else if (o instanceof Map) diff --git a/SerialX-json/.classpath b/SerialX-json/.classpath deleted file mode 100644 index 002ad57..0000000 --- a/SerialX-json/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SerialX-json/.project b/SerialX-json/.project deleted file mode 100644 index 873aaef..0000000 --- a/SerialX-json/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - SerialX-json - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index f468198..45060e3 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -1,5 +1,9 @@ package org.ugp.serialx.json; +import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.isOneOf; +import static org.ugp.serialx.Utils.multilpy; + import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.io.File; @@ -22,15 +26,17 @@ import org.ugp.serialx.converters.BooleanConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.json.converters.JsonCharacterConverter; -import org.ugp.serialx.json.converters.JsonNumberConverter; -import org.ugp.serialx.json.converters.JsonObjectConverter; import org.ugp.serialx.converters.NullConverter; import org.ugp.serialx.converters.StringConverter; import org.ugp.serialx.converters.VariableConverter; +import org.ugp.serialx.json.converters.JsonCharacterConverter; +import org.ugp.serialx.json.converters.JsonNumberConverter; +import org.ugp.serialx.json.converters.JsonObjectConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import javafx.beans.binding.When; + /** * This is implementation of {@link JussSerializer} for serializing in Json! * It should generate and work with .json files! @@ -143,7 +149,7 @@ public String Var(String name, T value, boolean isValue) @Override public Object put(String variableName, Object variableValue) { - if (Serializer.isOneOf(variableName.charAt(0), '"', '\'') && Serializer.isOneOf(variableName.charAt(variableName.length()-1), '"', '\'')) + if (isOneOf(variableName.charAt(0), '"', '\'') && isOneOf(variableName.charAt(variableName.length()-1), '"', '\'')) variableName = variableName.substring(1, variableName.length()-1); return super.put(variableName, variableValue); } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java index 4850d18..1aaec5b 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -8,7 +8,7 @@ public class JsonNumberConverter extends NumberConverter { public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { if (obj instanceof Number) - return decimalFormatter != null ? decimalFormatter.format(obj) : obj.toString(); + return format((Number) obj); return CONTINUE; } } diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml new file mode 100644 index 0000000..bc08a57 --- /dev/null +++ b/SerialX-juss/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + juss + 1.3.7 + + SerialX-juss + SerialX support for Java Universal Serial Script data format, custom default format of SerialX! + \ No newline at end of file diff --git a/SerialX-operators/.classpath b/SerialX-operators/.classpath deleted file mode 100644 index 002ad57..0000000 --- a/SerialX-operators/.classpath +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SerialX-operators/.project b/SerialX-operators/.project deleted file mode 100644 index 27a03a7..0000000 --- a/SerialX-operators/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - SerialX-operators - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index f1d1466..ab17c54 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -1,7 +1,8 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Serializer.fastReplace; -import static org.ugp.serialx.Serializer.isOneOf; +import static org.ugp.serialx.Utils.fastReplace; +import static org.ugp.serialx.Utils.isOneOf; +import static org.ugp.serialx.Utils.multilpy; import java.util.ArrayList; import java.util.Arrays; @@ -10,7 +11,6 @@ import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.ArrayConverter; import org.ugp.serialx.converters.DataParser; @@ -260,7 +260,7 @@ public static Object mult(Object cof, Object cof2, int sign) if (cof2 instanceof Number) { if (!(cof instanceof Number)) - return Serializer.multilpy(cof.toString(), ((Number) cof2).intValue() * sign).toString(); + return multilpy(cof.toString(), ((Number) cof2).intValue() * sign).toString(); if (cof instanceof Double || cof2 instanceof Double) return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; @@ -274,7 +274,7 @@ public static Object mult(Object cof, Object cof2, int sign) return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; } - return Serializer.multilpy(cof2.toString(), ((Number) cof).intValue() * sign).toString(); + return multilpy(cof2.toString(), ((Number) cof).intValue() * sign).toString(); } /** @@ -426,7 +426,7 @@ else if (ch == '}' || ch == ']') brackets--; else if (brackets == 0) { - if (Serializer.isOneOf(ch, operators)) + if (isOneOf(ch, operators)) hasOpr = isCof = 0; else if (oldCh <= 32 && isCof == 1) return false; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 44b593d..7509862 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Utils.indexOfNotInObj; import java.lang.reflect.Array; import java.util.Collection; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index ffeee37..9925c3a 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -1,9 +1,9 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Utils.indexOfNotInObj; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Serializer.NULL; +import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.DataParser; /** diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index c8d4945..9bd7cb6 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Serializer.indexOfNotInObj; +import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.converters.operators.ArithmeticOperators.getTerms; import java.util.List; diff --git a/pom.xml b/pom.xml index db0f207..00e37a7 100644 --- a/pom.xml +++ b/pom.xml @@ -11,6 +11,7 @@ SerialX-core SerialX-devtools SerialX-operators + SerialX-juss SerialX root @@ -40,7 +41,7 @@ - 1.8 + 8 1.3.7 UTF-8 @@ -55,7 +56,6 @@ org.apache.maven.plugins maven-compiler-plugin - 3.8.0 ${java.version} From 3a1d678a5254c3905b7f762ea9f67525e317ef2d Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 13 Nov 2023 16:16:17 +0100 Subject: [PATCH 08/75] refactor ObjectConverter, creating Utils, bitwise optimizations, preparation for variable deserialization and abolishment of scope runtime temporary inharitance, other refactorings, --- .../java/org/ugp/serialx/GenericScope.java | 161 +++++-- .../java/org/ugp/serialx/LogProvider.java | 10 +- .../src/main/java/org/ugp/serialx/Scope.java | 124 +++--- .../main/java/org/ugp/serialx/Serializer.java | 23 +- .../src/main/java/org/ugp/serialx/Utils.java | 95 +++- .../ugp/serialx/converters/DataParser.java | 2 +- .../serialx/converters/ProtocolConverter.java | 412 ++++++++++++++++++ .../serialx/converters/imports/Import.java | 19 +- .../converters/imports/ImportConverter.java | 267 ------------ .../converters/imports/ImportsProvider.java | 223 +++++++++- .../protocols/SelfSerializableProtocol.java | 11 +- .../protocols/SerializationProtocol.java | 2 +- .../UniversalObjectInstantiationProtocol.java | 15 +- SerialX-json/pom.xml | 2 +- .../org/ugp/serialx/json/JsonSerializer.java | 4 +- .../json/converters/JsonObjectConverter.java | 6 +- SerialX-juss/pom.xml | 8 + .../org/ugp/serialx/juss}/JussSerializer.java | 41 +- .../juss}/converters/ArrayConverter.java | 70 +-- .../juss/converters/ImportConverter.java | 79 ++++ .../juss/converters/ObjectConverter.java | 199 +++++++++ .../juss/converters/ObjectConverterOld.java | 23 +- .../juss}/converters/OperationGroups.java | 11 +- .../juss}/converters/VariableConverter.java | 14 +- .../operators/ArithmeticOperators.java | 20 +- .../ConditionalAssignmentOperators.java | 8 +- 26 files changed, 1316 insertions(+), 533 deletions(-) create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java delete mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/JussSerializer.java (94%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/converters/ArrayConverter.java (64%) create mode 100644 SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java create mode 100644 SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java rename SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java => SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java (96%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/converters/OperationGroups.java (96%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/converters/VariableConverter.java (95%) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index bdb25df..3ca29a7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -17,7 +17,6 @@ import java.util.function.Predicate; import org.ugp.serialx.Utils.NULL; -import org.ugp.serialx.converters.ArrayConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -110,7 +109,7 @@ else if (obj instanceof Collection) else if (obj instanceof Map) return valuesCount() <= 0 && variables().equals(obj); else if (obj != null && obj.getClass().isArray()) - return variablesCount() <= 0 && Objects.deepEquals(toValArray(), ArrayConverter.fromAmbiguous(obj)); + return variablesCount() <= 0 && Objects.deepEquals(toValArray(), Utils.fromAmbiguousArray(obj)); return super.equals(obj); } @@ -277,10 +276,82 @@ public V get(KeyT variableKey, V defaultValue) { V obj = (V) variables().get(variableKey); if (obj == null) - return (V) defaultValue; + return defaultValue; return obj instanceof NULL ? null : obj; } + /** + * @param pathToValue | Array with variables creating path to required value, nested in multiple sub-scopes. + * + * @return Value of variable at given path. If no path is given (length is 0) then this {@link GenericScope} will be returned.
+ * If 1 path argument is given then this behaves similarly to {@link GenericScope#get(Object)}.
+ * if 2+ path arguments are given then it will search the sub-scopes and return first match value. For example:
+ * Consider this scope tree:
+ *
+	 * 
+	 * {
+	 *   125: {
+	 *   	"hello": {
+	 *   		"value" true
+	 *   	}
+	 *   }
+	 * }
+	 * 
+	 * 
+ * Then to get value of "value" you can do scope.get(125, "hello", "value")!
+ * If there is no other variable called "value" in the scope tree then you can also simplify it to scope.get("value"), but make sure that there is no equally-named variable!
+ * Note: Make sure that you are not calling {@link GenericScope#get(Object, Object)} by accident when you are using inline vargas array (unspecified count of arguments)! + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public V get(KeyT... pathToValue) + { + try + { + if (pathToValue.length <= 0) + return (V) this; + Object obj = get((KeyT) pathToValue[0]); + if (obj instanceof GenericScope) + return ((GenericScope) obj).get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); + for (Map.Entry var : varEntrySet()) + if (var.getValue() instanceof GenericScope) + try + { + GenericScope sc = (GenericScope) var.getValue(); + if ((sc = sc.getGenericScope(pathToValue[0])) != null) + return sc.get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); + } + catch (Exception e) {} + + return (V) obj; + } + catch (ClassCastException e) + {} + return null; + } + + /** + * @param variableKey | Variables name. + * @param cls | Default value to return. + * @param defaultValue | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. + * + * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one! + * + * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)} + * + * @since 1.3.7 + */ + public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception + { + V obj = get(variableKey, defaultValue); + if (obj != null && obj.getClass() == cls) + return obj; + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(cls); + return obj; + } + /** * @param variableKey | Variables name to search for. * @@ -312,7 +383,7 @@ public boolean containsIndependentValue(ValT value) * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! * {@link IndexOutOfBoundsException} will be thrown if index is too big! * - * @return Independent value with valueIndex. + * @return Independent value with valueIndex of this {@link GenericScope}! * * @since 1.2.0 */ @@ -323,6 +394,26 @@ public V get(int valueIndex) return obj instanceof NULL ? null : obj; } + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * @param cls | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. + * + * @return Independent value with valueIndex of this converted to object of cls! + * + * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! + * + * @since 1.3.7 + */ + public V get(int valueIndex, Class cls) throws Exception + { + V obj = get(valueIndex); + if (obj != null && obj.getClass() == cls) + return obj; + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(cls); + return obj; + } + /** * @param value | Independent value to add into array of values. * @@ -383,10 +474,10 @@ public GenericScope getGenericScope(int scopeValueIndex) } /** - * @param scopesPath | Array with variables creating path to required scope. + * @param pathToScope | Array with variables creating path to required scope. * - * @return Sub-scope stored by variable with required name (last element) in inserted path or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! - * This search will also includes sub-scopes of scope but variables from lower ones are prioritize!
+ * @return Sub-scope stored by variable with required name (last element of pathToScope) or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! + * This search will also includes sub-scopes stored by variables of this scope while variables from lower ones are prioritize!
* If this function is called with no arguments then self will be returned! * Note: Remember that this search includes variables only, no values!
* Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) @@ -394,30 +485,14 @@ public GenericScope getGenericScope(int scopeValueIndex) * @since 1.2.0 */ @SuppressWarnings("unchecked") - public GenericScope getGenericScope(K... scopesPath) + public GenericScope getGenericScope(K... pathToScope) { - try - { - if (scopesPath.length <= 0) - return (GenericScope) this; - Object obj = get((KeyT) scopesPath[0]); - if (obj instanceof GenericScope) - return ((GenericScope) obj).getGenericScope(scopesPath = Arrays.copyOfRange(scopesPath, 1, scopesPath.length)); - for (Map.Entry var : varEntrySet()) - if (var.getValue() instanceof GenericScope) - try - { - GenericScope sc = (GenericScope) var.getValue(); - if ((sc = sc.getGenericScope(scopesPath[0])) != null) - return sc.getGenericScope(scopesPath = Arrays.copyOfRange(scopesPath, 1, scopesPath.length)); - } - catch (Exception e) {} - - if (containsVariable((KeyT) scopesPath[0])) - LogProvider.instance.logErr("Variable with name \"" + scopesPath[0] + "\" does exists! However its value is not instance of scope, use \"get\" function instead if possible!", null); - } - catch (ClassCastException e) - {} + Object obj = get((KeyT[]) pathToScope); + if (obj instanceof GenericScope) + return (GenericScope) obj; + + if (containsVariable((KeyT) pathToScope[0])) + LogProvider.instance.logErr("Variable with name \"" + pathToScope[0] + "\" does exists! However its value is not instance of scope, use \"get\" function instead if possible!", null); return null; } @@ -657,7 +732,7 @@ public GenericScope inheritParent() * * @since 1.3.0 */ - public GenericScope addAll(GenericScope scope) + public GenericScope addAll(GenericScope scope) { values().addAll(scope.values()); variables().putAll(scope.variables()); @@ -719,23 +794,27 @@ public boolean isEmpty() */ public GenericScope getParent() { - return getParent(false); + return getParent(1); } /** - * @param absoluteParent | If true, absolute parent of this scope will be returned (parent of parent of parent...)! - * - * @return The parent scope of this scope or null if this scope has no parent such as default one in file. + * @param depth | Positive number representing how many times will this method call itself...
For example 0 or less = this, 1 = parent, 2 = parentOfParent (parent.getParent()) and so on... + * If you want to get the root parent (the one that has no parent), simply put a big number as depth. 99 should be enough! + * + * @return The parent scope based on depth or null if this scope has no parent which means its already root (default one in file). + * If depth was bigger than 1, null will be never returned, last not null parent will be returned instead!
* * @since 1.3.2 */ - public GenericScope getParent(boolean absoluteParent) + public GenericScope getParent(int depth) { - if (!absoluteParent) - return parent; - GenericScope parent = this.parent; - for (GenericScope tmpPar; parent != null && (tmpPar = parent.getParent()) != null; parent = tmpPar); - return parent; + if (depth < 1) + return this; + + GenericScope parentsParent; + if (depth == 1 || parent == null || (parentsParent = parent.getParent(--depth)) == null) + return parent; + return parentsParent; } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java index 79c3039..5ab4f08 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java @@ -15,19 +15,21 @@ public class LogProvider public static LogProvider instance = new LogProvider(); /** - * @param object | Object to log in normal mode! + * @param obj | Object to log in normal mode! * * @since 1.3.5 */ - public void logOut(Object object) + public void logOut(Object obj) { - System.out.println(object); + System.out.println(obj); } /** - * @param object | Object to log in error mode! + * @param obj | Object to log in error mode! * @param ex | Exception that cause the error! * + * @throws RuntimeException | Of "ex" if exception re-throwing is enabled! + * * @since 1.3.5 */ public void logErr(Object obj, Throwable ex) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index 61c5839..c0defa6 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -17,7 +17,6 @@ import java.util.Objects; import java.util.function.Predicate; -import org.ugp.serialx.converters.ArrayConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -101,7 +100,46 @@ public Scope(Map variablesMap, Collection values, GenericScope T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception + { + T obj = super.toObject(objClass, protocolsToUse); + if (obj != null) + return obj; + + try + { + return into(objClass); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to create new instance of " + objClass.getName() + " because none of provided protocols were suitable and class introspection has failed as well!", e); + return null; + } } /** @@ -590,11 +628,13 @@ public Scope getSubScope(int subscopesOrderIndex) } /** - * @param scopesPath | Array with variable names creating path to required scope. + * @param pathToScope | Array with variable names creating path to required scope. * - * @return Sub-scope stored by variable with required name (last element) in inserted path or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! - * This search will also includes sub-scopes of scope but variables from lower ones are prioritize!
+ * @return Sub-scope stored by variable with required name (last element of pathToScope) or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! + * This search will also includes sub-scopes stored by variables of this scope while variables from lower ones are prioritize!
* If this function is called with no arguments then self will be returned! + * Note: Remember that this search includes variables only, no values!
+ * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) *
*
 	 * 
@@ -614,11 +654,11 @@ public Scope getSubScope(int subscopesOrderIndex)
 	 * 
 	 * @since 1.2.0
 	 */
-	public Scope getScope(String... scopesPath)
+	public Scope getScope(String... pathToScope)
 	{
 		try
 		{
-			return (Scope) getGenericScope(scopesPath);
+			return (Scope) getGenericScope(pathToScope);
 		}
 		catch (ClassCastException e)
 		{
@@ -807,7 +847,7 @@ public Scope getScopesWith(String varName, Predicate condition)
 	public Scope getScopesWith(String varName, Predicate condition, boolean includeSubScopes)
 	{
 		Scope result = new Scope(null, null, getParent());
-		
+
 		for (Entry myVar : varEntrySet())
 			if (myVar.getValue() instanceof Scope)
 				try
@@ -835,37 +875,6 @@ else if (includeSubScopes)
 		return result;
 	}
 	
-	/**
-	 * @param objClass | Object of class to create using protocols.
-	 * @param protocolsToUse | Registry of protocols to use.
-	 * 
-	 * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! 
-	 * If there were no suitable deserialization protocols found, {@link Scope#into(Class, String...)} will be used!
-	 * 
-	 * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}!
-	 * 
-	 * @see Scope#into(Class, String...)
-	 * @see Scope#intoNew(Class, GenericScope, String...)
-	 * 
-	 * @since 1.3.5
-	 */
-	public  T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception
-	{
-		T obj = super.toObject(objClass, protocolsToUse);
-		if (obj != null)
-			return obj;
-		
-		try
-		{
-			return into(objClass);
-		}
-		catch (Exception e)
-		{
-			LogProvider.instance.logErr("Unable to create new instance of " + objClass.getName() + " because none of provided protocols were suitable and class introspection has failed as well!", e);
-			return null;
-		}
-	}
-	
 	/**
 	 * @param objCls | Class of object to instantiate!
 	 * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! PropertyDescriptors of these fields will be obtained using Scope.getPropertyDescriptorsOf(Class, String)! This is used only as a last (default) option!
@@ -897,7 +906,7 @@ public  T into(Class objCls, String... fieldNamesToUse) throws Introspecti
 	 * 
 	 * @since 1.3.5  
 	 */
-	public  T into(Object obj, String... fieldNamesToUse) throws IntrospectionException, Exception
+	public  T into(T obj, String... fieldNamesToUse) throws IntrospectionException, Exception
 	{
 		return into(obj, this, fieldNamesToUse);
 	}
@@ -957,7 +966,7 @@ public static Scope from(Object obj, String... fieldNamesToUse) throws Exception
 			return new Scope();
 		
 		if (obj.getClass().isArray())
-			return new Scope(ArrayConverter.fromAmbiguous(obj));
+			return new Scope(Utils.fromAmbiguousArray(obj));
 		
 		if (obj instanceof Scope)
 		{
@@ -996,22 +1005,23 @@ public static Scope from(Object obj, List fieldsToUse) throw
 	}
 	
 	/**
-	 * @param newInstance | New instance of specific {@link Scope}!
+	 * @param newInstance | New instance of specific {@link GenericScope} with {@link String} keys!
 	 * @param obj | Object to create scope from!
 	 * @param fieldsToUse | List of {@link PropertyDescriptor}s representing fields of object to map into scopes variables using getters (read method)!
 	 * 
-	 * @return Scope (newInstance) structured from given obj by mapping obj's fields into variables of created scope via given {@link PropertyDescriptor}s (fieldsToUse)!
+	 * @return Scope (newInstance) structured/populated from given obj by mapping obj's fields into variables of created scope via given {@link PropertyDescriptor}s (fieldsToUse)!
 	 * 
 	 * @throws Exception if calling of some {@link PropertyDescriptor}s read method fails (should not happen often)!
 	 * 
 	 * @since 1.3.5
 	 */
-	public static Scope from(Scope newInstance, Object obj, List fieldsToUse) throws Exception
+	@SuppressWarnings("unchecked")
+	public static > S from(S newInstance, Object obj, List fieldsToUse) throws Exception
 	{
 		//if (variablesToUse != null)
 		//variablesToUse = AutoProtocol.getPropertyDescriptorsOf(obj.getClass());
 		for (PropertyDescriptor var : fieldsToUse) 
-			newInstance.put(var.getName(), var.getReadMethod().invoke(obj));
+			((GenericScope) newInstance).put(var.getName(), var.getReadMethod().invoke(obj));
 		return newInstance;
 	}
 	
@@ -1064,7 +1074,7 @@ New object instance (return)
 	 * @since 1.3.5
 	 */
 	@SuppressWarnings("unchecked")
-	public static  T intoNew(Class objCls, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception
+	public static  T intoNew(Class objCls, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception
 	{
 		if (objCls == null)
 			return null;
@@ -1079,7 +1089,7 @@ public static  T intoNew(Class objCls, GenericScope fromScope,
 		
 		if (GenericScope.class.isAssignableFrom(objCls))
 		{
-			GenericScope result = ((GenericScope) fromScope).clone((Class>)objCls);
+			GenericScope result = ((GenericScope) fromScope).clone((Class>)objCls);
 			if (fieldNamesToUse != null && fieldNamesToUse.length > 0)
 				result.variables().keySet().retainAll(Arrays.asList(fieldNamesToUse));
 			return (T) result;
@@ -1154,7 +1164,7 @@ Action with obj (return)
 	 * @since 1.3.5
 	 */
 	@SuppressWarnings("unchecked")
-	public static  T into(Object obj, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception
+	public static  T into(T obj, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception
 	{
 		if (obj == null)
 			return null;
@@ -1162,21 +1172,21 @@ public static  T into(Object obj, GenericScope fromScope, String..
 		{
 			for (int i = 0, arrLen = Array.getLength(obj), scSize = fromScope.valuesCount(); i < arrLen && i < scSize; i++)
 				Array.set(obj, i, fromScope.get(i));
-			return (T) obj;
+			return obj;
 		}
 		
 		if (obj instanceof GenericScope)
 		{
-			((GenericScope) obj).addAll(fromScope);
+			((GenericScope) obj).addAll(fromScope);
 			if (fieldNamesToUse != null && fieldNamesToUse.length > 0)
-				((GenericScope) obj).variables().keySet().retainAll(Arrays.asList(fieldNamesToUse));
-			return (T) obj;
+				((GenericScope) obj).variables().keySet().retainAll(Arrays.asList(fieldNamesToUse));
+			return obj;
 		}
 		
 		if (obj instanceof Collection)
 		{	
 			((Collection) obj).addAll(fromScope.values());
-			return (T) obj;
+			return obj;
 		}
 		
 		if (obj instanceof Map)
@@ -1184,10 +1194,10 @@ public static  T into(Object obj, GenericScope fromScope, String..
 			((Map) obj).putAll(fromScope.variables());
 			if (fieldNamesToUse != null && fieldNamesToUse.length > 0)
 				((Map) obj).keySet().retainAll(Arrays.asList(fieldNamesToUse));
-			return (T) obj;
+			return obj;
 		}
 		
-		return (T) into(obj, fromScope, getPropertyDescriptorsOf(obj.getClass(), fieldNamesToUse));
+		return into(obj, fromScope, getPropertyDescriptorsOf(obj.getClass(), fieldNamesToUse));
 	}
 	
 	/**
@@ -1202,11 +1212,11 @@ public static  T into(Object obj, GenericScope fromScope, String..
 	 * @since 1.3.5
 	 */
 	@SuppressWarnings("unchecked")
-	public static  T into(T obj, GenericScope fromScope, List fieldsToUse) throws Exception
+	public static  T into(T obj, GenericScope fromScope, List fieldsToUse) throws Exception
 	{
 		for (PropertyDescriptor var : fieldsToUse) 
 		{
-			Object varValue = ((GenericScope) fromScope).get(var.getName(), VOID);
+			Object varValue = ((GenericScope) fromScope).get(var.getName(), VOID);
 			if (varValue != VOID)
 				var.getWriteMethod().invoke(obj, varValue);
 		}
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
index ccae28e..9b5476b 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
@@ -56,7 +56,7 @@ public abstract class Serializer extends Scope
 	 * 
 	 * @since 1.3.2
 	 */
-	public static final ParserRegistry COMMON_PARSERS = new ParserRegistry(new StringConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
+	public static final ParserRegistry COMMON_PARSERS = new ParserRegistry(new StringConverter(), /* TODO: new ProtocolConverter() */ new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
 	
 	protected ParserRegistry parsers;
 	protected ProtocolRegistry protocols;
@@ -132,19 +132,6 @@ public Serializer(Registry parsers, ProtocolRegistry protocols, Map<
 		if (protocols != null)
 			setProtocols(protocols);
 	}
-	
-	@Override
-	public Scope clone() 
-	{
-		try 
-		{
-			return clone(getClass());
-		}
-		catch (Exception e) 
-		{
-			return new JussSerializer(variables(), values(), getParent());
-		}
-	}
 
 	@Override
 	public > S clone(Class typeOfClone) throws Exception
@@ -186,7 +173,7 @@ public  T toObject(Class objClass) throws Exception
 	 * @see Serializer#into(Object, Serializer, String...)
 	 */
 	@Override
-	public  T into(Object obj, String... fieldNamesToUse) throws IntrospectionException, Exception 
+	public  T into(T obj, String... fieldNamesToUse) throws IntrospectionException, Exception 
 	{
 		return Serializer.into(obj, this, fieldNamesToUse);
 	}
@@ -702,7 +689,7 @@ else if (ch == '/' && i < len-1)
 						}
 						else
 						{
-							if (ch == '{' || ch == '[')
+							if (ch | ' ') == '{' || ch == '[')
 								brackets++;
 							else if (ch == '}' || ch == ']')
 							{
@@ -844,7 +831,7 @@ else if (ch == '/' && fromIndex < len-1)
 					}
 					else 
 					{
-						if (ch == '{' || ch == '[')
+						if (ch | ' ') == '{' || ch == '[')
 							brackets++;
 						else if (ch == '}' || ch == ']')
 						{
@@ -1022,7 +1009,7 @@ public static  T into(Object obj, Serializer fromSerializer, String... fieldN
 		catch (IOException e)
 		{}
 		
-		return Scope.into(obj, fromSerializer, fieldNamesToUse);
+		return (T) Scope.into(obj, fromSerializer, fieldNamesToUse);
 	}
 	
 	/**
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
index a9b8d48..11e1025 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
@@ -9,6 +9,7 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
@@ -24,8 +25,14 @@
 import org.ugp.serialx.converters.DataParser.ParserRegistry;
 import org.ugp.serialx.protocols.SerializationProtocol;
 
-
-public class Utils {
+/**
+ * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection.
+ * 
+ * @author PETO
+ * 
+ * @since 1.3.7
+ */
+public final class Utils {
 	private Utils() {}
 	
 	/**
@@ -99,6 +106,8 @@ public static String StreamToString(Reader input, int endlMode) throws IOExcepti
 		return sb.toString();
 	}
 	
+	/* Reflect */
+	
 	/**
 	 * @param cls | Class to invoke method from.
 	 * @param name | Name of public static method to be called.
@@ -421,6 +430,8 @@ else if (objs[i] instanceof Class)
 		return classes;
 	}
 	
+	/* Characters */
+	
 	/**
 	 * @param ch | String to multiply!
 	 * @param times | Count of multiplication!
@@ -522,9 +533,9 @@ public static String[] splitValues(String s, int limit, boolean oneOrMore, char[
 					result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i).trim());
 					count++;
 				}
-				else if (ch == '{' || ch == '[')
+				else if ((ch | ' ') == '{')
 					brackets++;
-				else if (ch == '}' || ch == ']')
+				else if ((ch | ' ') == '}')
 				{
 					if (brackets > 0)
 						brackets--;
@@ -551,7 +562,7 @@ else if (quote % 2 != 0)
 	 * @param s | CharSequence to search!
 	 * @param oneOf | Characters to find!
 	 * 
-	 * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'!
+	 * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1!
 	 * 
 	 * @since 1.3.0
 	 */
@@ -565,7 +576,7 @@ public static int indexOfNotInObj(CharSequence s, char... oneOf)
 	 * @param firstIndex | If true, first index will be returned, if false last index will be returned.
 	 * @param oneOf | Characters to find!
 	 * 
-	 * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'!
+	 * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1!
 	 * 
 	 * @since 1.3.5
 	 */
@@ -586,9 +597,9 @@ public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... on
 					if (firstIndex)
 						return found;
 				}
-				else if (ch == '{' || ch == '[')
+				else if ((ch | ' ') == '{')
 					brackets++;
-				else if (ch == '}' || ch == ']')
+				else if ((ch | ' ') == '}')
 				{
 					if (brackets > 0)
 						brackets--;
@@ -643,9 +654,9 @@ public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, b
 						match = 0;
 					}
 				}
-				else if (ch == '{' || ch == '[')
+				else if ((ch | ' ') == '{')
 					brackets++;
-				else if (ch == '}' || ch == ']')
+				else if ((ch | ' ') == '}')
 				{
 					if (brackets > 0)
 						brackets--;
@@ -673,11 +684,11 @@ public static String fastReplace(String str, String target, CharSequence replace
 	    int targetLength = target.length();
 	    if (targetLength == 0) 
 	        return str;
-	    
+
 	    int i1 = 0, i2 = str.indexOf(target);
 	    if (i2 < 0) 
 	        return str;
-	    
+
 	    StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2);
 	    do 
 	    {
@@ -740,6 +751,66 @@ public static String showPosInString(CharSequence str, int pos)
 		return str + "\n" + multilpy(' ', pos) + "^";	
 	}
 	
+	/* Arrays */
+	
+	/**
+	 * @param sourceArray | Array to cast!
+	 * @param toType | Type to cast array in to!
+	 * 
+	 * @return Array object casted in to required type!
+	 * 
+	 * @since 1.3.2
+	 */
+	public static Object castArray(Object[] sourceArray, Class toType)
+	{
+		int len = sourceArray.length;
+		Object arr = Array.newInstance(ToClasses(toType)[0], len);
+		for (int i = 0; i < len; i++) 
+			Array.set(arr, i, sourceArray[i]);
+		return arr;
+	}
+	
+	/**
+	 * @param arr1 | Object one that might be array!
+	 * @param arr2 | Object two that might be array!
+	 * 
+	 * @return New array consisting of array 1 and array 2!
+	 * 
+	 * @throws IllegalArgumentException if object one is not an array!
+	 * 
+	 * @since 1.3.2
+	 */
+	public static Object[] mergeArrays(Object arr1, Object arr2) 
+	{
+		Object[] array1 = fromAmbiguousArray(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguousArray(arr2) : new Object[] { arr2 };
+		Object[] result = Arrays.copyOf(array1, array1.length + array2.length);
+	    System.arraycopy(array2, 0, result, array1.length, array2.length);
+	    return result;
+	}
+	
+	/**
+	 * @param array | Object that might be array!
+	 * 
+	 * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned!
+	 * 
+	 * @throws IllegalArgumentException if the specified object is not an array!
+	 * 
+	 * @since 1.3.2 (since 1.3.7 moved from ArrayConverter)
+	 */
+	public static Object[] fromAmbiguousArray(Object array)
+	{
+		if (array instanceof Object[])
+			return (Object[]) array;
+		
+		int len = Array.getLength(array);
+		Object[] arr = new Object[len];
+		for (int i = 0; i < len; i++) 
+			arr[i] = Array.get(array, i);
+		return arr;
+	}
+	
+	/* Others... */
+	
 	/**
 	 * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content!
 	 * 
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
index 1eee489..b53fb83 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
@@ -41,7 +41,7 @@ public interface DataParser
 	 * 
 	 * @since 1.3.0
 	 */
-	public static final ParserRegistry REGISTRY = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
+	public static final ParserRegistry REGISTRY = new ParserRegistry(/* new OperationGroups(), new VariableConverter(),*/ new StringConverter(), /*new ObjectConverter(),*/ /*TODO: remove new ArrayConverter(),*/ new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
 	
 	/**
 	 * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)!
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java
new file mode 100644
index 0000000..bb04719
--- /dev/null
+++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java
@@ -0,0 +1,412 @@
+package org.ugp.serialx.converters;
+
+import static org.ugp.serialx.Utils.Instantiate;
+import static org.ugp.serialx.Utils.indexOfNotInObj;
+import static org.ugp.serialx.Utils.isOneOf;
+import static org.ugp.serialx.Utils.splitValues;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Base64;
+
+import org.ugp.serialx.GenericScope;
+import org.ugp.serialx.LogProvider;
+import org.ugp.serialx.Registry;
+import org.ugp.serialx.Scope;
+import org.ugp.serialx.Serializer;
+import org.ugp.serialx.Utils;
+import org.ugp.serialx.converters.imports.ImportsProvider;
+import org.ugp.serialx.protocols.SerializationProtocol;
+import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry;
+
+/**
+ * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions!
+ * This is also responsible for {@link Scope}!
+ * Its case sensitive!
+ * 
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + +
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
+
+ This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
+ This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
+ * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class ProtocolConverter implements DataConverter +{ + /** + * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) + */ + protected boolean useBase64IfCan = false; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) + { + int len; + if ((len = str.length()) > 0) + { + if ((str.charAt(0) | ' ') == '{' && (str.charAt(--len) | ' ') == '}') // Unwrap if wrapped in {} + str = str.substring(1, len).trim(); + + Class objClass; + if ((objClass = getProtocolExprClass(str, compilerArgs)) != null) // Get class of protocol expr or continue if there is none + return parse(myHomeRegistry, objClass, str, compilerArgs); + } + return CONTINUE; + } + + /** + * @param myHomeRegistry | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. + * @param objClass | Class of object to parse using {@link SerializationProtocol}. + * @param str | String that starts with {@link Class} of object to deserialized (it will be used with {@link SerializationProtocol#unserializeObj(ProtocolRegistry, Class, Object...)}). + * @param compilerArgs | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. + * + * @return Object od objClass parsed from str in accordance with compilerArgs! + * + * @since 1.3.7 + */ + protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String str, Object... compilerArgs) + { + if (objClass == IsSelectorScope.class) + { + StringBuilder sb = new StringBuilder(str); + sb.setCharAt(str.indexOf(' '), '='); + return myHomeRegistry.parse(sb.toString(), compilerArgs); + } + + if (compilerArgs.length < 5) + compilerArgs = Arrays.copyOf(compilerArgs, 5); + Class oldObjectClass = (Class) compilerArgs[4]; + compilerArgs[4] = objClass; + + String[] args = splitValues(str, ' '); + int nameIndex; + if (!isOneOf(args[0].charAt(0), '{', '[') && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation + { + String memberName = args[0].substring(nameIndex + 2); + if (args.length > 1) + return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); + + try + { + compilerArgs[4] = oldObjectClass; + return memberName.equals("class") ? objClass : memberName.equals("new") ? Instantiate(objClass) : objClass.getField(memberName).get(null); + } + catch (NoSuchFieldException e) + { + return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to obtain value of field \"" + memberName + "\" in class \"" + objClass.getSimpleName() + "\" because:", e); + e.printStackTrace(); + return null; + } + } + + try + { +// if ((ch = str.charAt(str.length()-1)) == ';' || ch == ',') +// throw new ClassNotFoundException(); + + Object[] objArgs = parseAll(myHomeRegistry, args, 1, true, compilerArgs); + if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objClass)) + return objArgs[0]; + compilerArgs[4] = oldObjectClass; + return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, objClass, objArgs); + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while unserializing instance of \"" + objClass.getName() + "\":", e); + e.printStackTrace(); + return null; + } + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + return toString(myHomeRegistry, arg, null, args); + } + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param preferedProtocol | Protocol to use preferably. + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) + { + if (arg == null) + return CONTINUE; + + if (useBase64IfCan && arg instanceof Serializable) + return CONTINUE; + + if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) + { + Object[] objArgs; + Class oldObjectClass = null; + try + { + int tabs = 0, index = 0; + if (args.length > 1 && args[1] instanceof Integer) + tabs = (int) args[1]; + + if (args.length > 2 && args[2] instanceof Integer) + index = (int) args[2]; + + if (args.length < 5) + args = Arrays.copyOf(args, 5); + oldObjectClass = (Class) args[4]; + args[4] = arg.getClass();; + + objArgs = preferedProtocol.serialize(arg); + StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, arg.getClass()) + (objArgs.length <= 0 ? "" : " ")); + + args = args.clone(); + for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) + { + if (args.length > 2) + args[2] = index + 1; + sb.append(myHomeRegistry.toString(objArgs[i], args)); + if (i < objArgs.length-1) + if (sb.length() > sizeEndl) + { + sb.append('\n'); + for (int j = 0; j < tabs+1; j++) + sb.append('\t'); + sizeEndl += 10000; + } + else + sb.append(' '); + } + + args[4] = oldObjectClass; + return index > 0 && objArgs.length > 0 ? sb.insert(0, '{').append('}') : sb; + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while serializing instance of \"" + arg.getClass().getName() + "\":", e); + e.printStackTrace(); + } + args[4] = oldObjectClass; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + if (obj instanceof Scope && ((Scope) obj).isEmpty()) + return "Empty scope!"; + else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) + return "Multiline char sequence!"; + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); + } + + /** + * @return True if program is forced to use {@link Base64} serialization on {@link Serializable} objects. + * This might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public boolean isUseBase64IfCan() + { + return useBase64IfCan; + } + + /** + * @param useBase64IfCan | Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public void setUseBase64IfCan(boolean useBase64IfCan) + { + this.useBase64IfCan = useBase64IfCan; + } + + /** + * @param obj | Object to get protocol for! + * @param mode | Protocol mode! + * @param args | Parser args to get protocol from! + * + * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
+ * Note: This is mainly used by {@link ObjectConverter}! + * + * @since 1.3.5 + */ + public static SerializationProtocol getProtocolFor(Object obj, byte mode, Object[] args) + { + if (args.length > 3) + { + if (args[3] instanceof ProtocolRegistry) + return ((ProtocolRegistry) args[3]).GetProtocolFor(obj, mode); + else if (args[3] instanceof SerializationProtocol) + return (SerializationProtocol) args[3]; + } + + return SerializationProtocol.REGISTRY.GetProtocolFor(obj, mode); + } + + /** + * @param str | String to check protocol class for! + * + * @return Class of the protocol or null if inserted statement is not protocol expression! + * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! + * + * @since 1.3.0 + */ + public static Class getProtocolExprClass(String str, Object... compilerArgs) + { + int i = 0, len = str.length(); + for (char ch; i < len; i++) + if ((ch = str.charAt(i)) == ' ' || ch == ':') + break; + + try + { + Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ProtocolConverter.class.getClassLoader()); + if (cls != null) + return cls; + for (char ch; i < len; i++) + { + if ((ch = str.charAt(i)) > 32) + if ((ch | ' ') == '{') + return IsSelectorScope.class; + else + return null; + } + } + catch (ClassNotFoundException e) + {} + return null; + } + + /** + * @param registry | Registry to use! + * @param strs | Source strings to parse using suitable parser from registry. + * @param from | Start index to begin from! + * @param trim | If true, all strings will be trimed before parsing! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Array of parsed objects, each parsed using {@link DataParser#parseObj(String, Object...)} + * + * @since 1.3.0 + */ + public static Object[] parseAll(ParserRegistry registry, String strs[], int from, boolean trim, Object... args) + { + Object[] objs = new Object[strs.length-from]; + for (int i = 0; from < strs.length; from++, i++) + objs[i] = registry.parse(trim ? strs[from].trim() : strs[from], args); + return objs; + } + + /** + * @return Array with 2 preferred sub-scope wrapping chars that are used during serialization by default. { and } + * + * @since 1.3.5 + */ + public static char[] primarySubscopeWrappers() + { + return new char[] {'{', '}'}; + } + + /** + * @return Array with 2 secondary sub-scope wrapping char. [ and ] + * + * @since 1.3.5 + */ + public static char[] secondarySubscopeWrappers() + { + return new char[] {'[', ']'}; + } + + /** + * @param cls | Class to invoke method from. + * @param oldCls | Old class to set (obtained from compilerArgs[4]). + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * @param compilerArgs | Arguments provided by parser. + * + * @return {@link Utils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
+ * Note: If you are not sure what this does, preferably use {@link Utils#InvokeStaticFunc(Class, String, Object...)}! + * + * @since 1.3.7 + */ + public static Object InvokeStaticFunc(Class cls, Class oldCls, String name, Object[] args, Object... compilerArgs) { + try + { + compilerArgs[4] = oldCls; + return Utils.InvokeStaticFunc(cls, name, args); + } + catch (InvocationTargetException e) + { + LogProvider.instance.logErr("Exception while calling method \"" + name + "\":", e); + e.printStackTrace(); + return null; + } + } + + /** + * Used internally by {@link ObjectConverter}!
+ * Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: + * + * shortenedSelectorLikeScope {

+ * //stuff... + * }; + *
+ * + * @author PETO + * + * @since 1.3.0 + */ + protected static class IsSelectorScope {}; +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java index 5ea69be..e2a9662 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -3,7 +3,7 @@ import java.lang.reflect.Type; import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.imports.ImportConverter.Imports; +import org.ugp.serialx.converters.imports.ImportsProvider.Imports; /** * This class is represents single import. It stores target class of import and its alias!
@@ -59,13 +59,24 @@ public Import(Class cls, String alias) * @param alias | Alias of class! * @param owner | Owner/provider of this Import! * + * @throws IllegalArgumentException | When alias is invalid! Alias should follow java class naming conventions without necessity of package specification! + * * @since 1.3.5 */ - public Import(Class cls, String alias, ImportsProvider owner) + public Import(Class cls, String alias, ImportsProvider owner) throws IllegalArgumentException { this.cls = cls; - this.alias = alias; - this.owner = owner; + + if (alias.isEmpty()) + throw new IllegalArgumentException("Import alias cant be empty! Try \"" + cls.getSimpleName() + "\" instead!"); + int ch0 = alias.charAt(0); + if (ch0 == '_' || (ch0 = ch0 | ' ') >= 'a' && ch0 <= 'z') + { + this.alias = alias; + this.owner = owner; + } + else + throw new IllegalArgumentException("Import alias \"" + alias + "\" is illegal! Alias cant begin with special char or number! Try \"_" + alias + "\" instead!"); } @Override diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java deleted file mode 100644 index 92f8524..0000000 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportConverter.java +++ /dev/null @@ -1,267 +0,0 @@ -package org.ugp.serialx.converters.imports; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; - -/** - * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! - * Parsing example: import java.util.ArrayList will add temporary {@link Import} of java.util.ArrayList or java.lang.String => Word will import java.lang.String as Word! - * Imports will be converted to string just by calling toString!
- *
- * This parser requires additional parser arg at index 0 of type {@link ImportsProvider} that will obtain managed imports! This arg is required during both parsing and converting! - * - * @author PETO - * - * @since 1.3.0 - */ -public class ImportConverter implements DataConverter -{ - /** - * List of global shared common registered imports! - * - * @since 1.3.0 - */ - public static final Imports IMPORTS = new Imports(new Import(Serializer.class), new Import(Scope.class), new Import(ArrayList.class), new Import(Math.class), new Import(Double.class), new Import(Integer.class), new Import(Double.class, "double"), new Import(Integer.class, "int"), new Import(String.class), new Import(System.class)); - - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (args.length > 0 && args[0] instanceof ImportsProvider) - { - Imports imports = ((ImportsProvider) args[0]).getImports(); - int index; - if (str.startsWith("import ")) - { - try - { - if ((str = str.substring(7).trim()).indexOf("=>") > -1) - return parse(myHomeRegistry, str, args); - imports.add(new Import(imports.forName(str), (ImportsProvider) args[0])); - } - catch (ClassNotFoundException e) - { - LogProvider.instance.logErr("Unable to import " + str + " because there is no such a class!", e); - } - return VOID; - } - else if ((index = (str = str.trim()).indexOf("=>")) > -1) - { - try - { - imports.add(new Import(imports.forName(str.substring(0, index).trim()), str.substring(index+2).trim(), (ImportsProvider) args[0])); - } - catch (ClassNotFoundException e) - { - LogProvider.instance.logErr("Unable to import " + str.substring(0, index).trim() + " because there is no such a class!", e); - } - return VOID; - } - } - return CONTINUE; - } - - @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) - { - if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) - { - return obj.toString(); - } - return CONTINUE; - } - - @Override - public String getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) - { - return "Import of " + ((Import) objToDescribe).getCls() + " as " + ((Import) objToDescribe).getClsAlias(); - } - - /** - * Collection used to store and operate with {@link Import}! - * - * @author PETO - * - * @since 1.3.5 - * - * @see ImportsProvider - */ - public static class Imports extends ArrayList implements Cloneable, ImportsProvider - { - private static final long serialVersionUID = 8487976264622823940L; - - /** - * Constructs an {@link Imports} with the specified initial capacity. - * - * @param initialSize | Initial capacity. - * - * @since 1.3.5 - */ - public Imports(int initialSize) - { - super(initialSize); - } - - /** - * Constructs an {@link Imports} with inserted imports c. - * - * @param c | Initial content of registry. - * - * @since 1.3.5 - */ - public Imports(Collection c) - { - super(c); - } - - /** - * Constructs an {@link Imports} with inserted imports. - * - * @param parsers | Initial content of registry. - * - * @since 1.3.5 - */ - public Imports(Import... imports) - { - addAll(imports); - } - - @Override - public Imports clone() - { - return new Imports(this); - } - - @Override - public Imports getImports() - { - return this; - } - - /** - * @param imports | Imports to add. - * - * @return {@link ArrayList#addAll(Collection)}; - * - * @since 1.3.5 - */ - public boolean addAll(Import... imports) - { - return super.addAll(Arrays.asList(imports)); - } - - /** - * @param aliasOrName | Alias of class or its full name! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - */ - public Class forName(String aliasOrName) throws ClassNotFoundException - { - return forName(aliasOrName, true, Imports.class.getClassLoader()); - } - - /** - * @param aliasOrName | Alias of class or its full name! - * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. - * @param loader | Class loader from which the class must be loaded. - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * If there are no dots in required alias and alias is not imported then null will be returned! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - */ - public Class forName(String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException - { - Class cls = getClassFor(aliasOrName); - if (cls != null) - return cls; - if (aliasOrName.indexOf('.') > 0) - return Class.forName(aliasOrName, initialize, loader); - /*try - { - return Class.forName("java.lang."+aliasOrName, initialize, loader); - } - catch (Exception e) - { - return null; - }*/ - return null; - } - - /** - * @param cls | Class to get alias for! - * - * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! - * - * @since 1.3.5 - */ - public String getAliasFor(Class cls) - { - for (int i = size() - 1; i >= 0; i--) - { - Import imp = get(i); - if (imp.equals(cls)) - return imp.getClsAlias(); - } - return cls.getName(); - } - - /** - * @param alias | Alias of class to obtain! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! - * - * @since 1.3.5 - */ - public Class getClassFor(String alias) - { - for (int i = size() - 1; i >= 0; i--) - { - Import imp = get(i); - if (imp.equals(alias)) - return imp.getCls(); - } - return null; - } - - /** - * @param owner | Owner of imports to get! - * - * @return Imports of provided owner stored by this list! - * - * @since 1.3.5 - */ - public Imports importsOf(ImportsProvider owner) - { - Imports imports = new Imports(); - for (Import imp : imports) - if (imp.getOwner() == owner) - imports.add(imp); - return imports; - } - - /** - * @param owner | Owner of imports to remove from this list! - * - * @since 1.3.5 - */ - public void removeImportsOf(ImportsProvider owner) - { - for (int i = size() - 1; i >= 0; i--) - if (get(i).getOwner() == owner) - remove(i); - } - } -} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java index 5afa8a4..06a89a7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -1,8 +1,13 @@ package org.ugp.serialx.converters.imports; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; -import org.ugp.serialx.converters.imports.ImportConverter.Imports; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; /** * This interface is supposed to be implemented by class that can provide array of imports! @@ -13,6 +18,21 @@ */ public interface ImportsProvider { + /** + * Cache of Classes to their respective names/aliases.
+ * Note: Treat as read only if possible! + * + * @since 1.3.7 + */ + public static final Map> CLASS_CACHE = new HashMap>(); + + /** + * List of global shared common registered imports! + * + * @since 1.3.0 + */ + public static final Imports IMPORTS = new Imports(new Import(Serializer.class), new Import(Scope.class), new Import(ArrayList.class), new Import(Math.class), new Import(Double.class), new Import(Integer.class), new Import(Double.class, "double"), new Import(Integer.class, "int"), new Import(String.class), new Import(System.class)); + /** * @return Array of provided imports! * @@ -83,8 +103,16 @@ public static Class forName(Object importProvider, String aliasOrName, boolea Class cls = getClassFor(importProvider, aliasOrName); if (cls != null) return cls; - if (aliasOrName.indexOf('.') > 0) - return Class.forName(aliasOrName, initialize, loader); + + if ((cls = CLASS_CACHE.get(aliasOrName)) != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + { + cls = Class.forName(aliasOrName, initialize, loader); + CLASS_CACHE.put(aliasOrName, cls); + return cls; + } + /*try { return Class.forName("java.lang."+aliasOrName, initialize, loader); @@ -127,4 +155,193 @@ public static Class getClassFor(Object importProvider, String alias) Imports imports = importsOf(importProvider); return imports != null ? imports.getClassFor(alias) : null; } + + /** + * Collection used to store and operate with {@link Import}! + * + * @author PETO + * + * @since 1.3.5 + * + * @see ImportsProvider + */ + public static class Imports extends ArrayList implements Cloneable, ImportsProvider + { + private static final long serialVersionUID = 8487976264622823940L; + + /** + * Constructs an {@link Imports} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public Imports(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link Imports} with inserted imports c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Collection c) + { + super(c); + } + + /** + * Constructs an {@link Imports} with inserted imports. + * + * @param parsers | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Import... imports) + { + addAll(imports); + } + + @Override + public Imports clone() + { + return new Imports(this); + } + + @Override + public Imports getImports() + { + return this; + } + + /** + * @param imports | Imports to add. + * + * @return {@link ArrayList#addAll(Collection)}; + * + * @since 1.3.5 + */ + public boolean addAll(Import... imports) + { + return super.addAll(Arrays.asList(imports)); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName) throws ClassNotFoundException + { + return forName(aliasOrName, true, Imports.class.getClassLoader()); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. + * @param loader | Class loader from which the class must be loaded. + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * If there are no dots in required alias and alias is not imported then null will be returned! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException + { + Class cls = getClassFor(aliasOrName); + if (cls != null) + return cls; + + if ((cls = CLASS_CACHE.get(aliasOrName)) != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + { + cls = Class.forName(aliasOrName, initialize, loader); + CLASS_CACHE.put(aliasOrName, cls); + return cls; + } + /*try + { + return Class.forName("java.lang."+aliasOrName, initialize, loader); + } + catch (Exception e) + { + return null; + }*/ + return null; + } + + /** + * @param cls | Class to get alias for! + * + * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! + * + * @since 1.3.5 + */ + public String getAliasFor(Class cls) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(cls)) + return imp.getClsAlias(); + } + return cls.getName(); + } + + /** + * @param alias | Alias of class to obtain! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! + * + * @since 1.3.5 + */ + public Class getClassFor(String alias) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(alias)) + return imp.getCls(); + } + return null; + } + + /** + * @param owner | Owner of imports to get! + * + * @return Imports of provided owner stored by this list! + * + * @since 1.3.5 + */ + public Imports importsOf(ImportsProvider owner) + { + Imports imports = new Imports(); + for (Import imp : imports) + if (imp.getOwner() == owner) + imports.add(imp); + return imports; + } + + /** + * @param owner | Owner of imports to remove from this list! + * + * @since 1.3.5 + */ + public void removeImportsOf(ImportsProvider owner) + { + for (int i = size() - 1; i >= 0; i--) + if (get(i).getOwner() == owner) + remove(i); + } + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java index 466a06c..d4eac0d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java @@ -11,16 +11,15 @@ */ public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol { - @Override - public Object[] serialize(SelfSerializable object) + public SelfSerializableProtocol() { - return object.serialize(); + super(SelfSerializable.class); } - + @Override - public Class applicableFor() + public Object[] serialize(SelfSerializable object) { - return SelfSerializable.class; + return object.serialize(); } @Override diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 16e65ba..7aab546 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -30,7 +30,7 @@ public abstract class SerializationProtocol * * @since 1.3.0 */ - public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(new UniversalObjectInstantiationProtocol(), new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); + public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(new UniversalObjectInstantiationProtocol<>(Object.class), new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); /** * This mode is for protocols that are used for serialization only! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java index c058b89..b941f2b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java @@ -18,6 +18,18 @@ */ public class UniversalObjectInstantiationProtocol extends SerializationProtocol { + protected final Class applicableFor; + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * + * @since 1.3.7 + */ + public UniversalObjectInstantiationProtocol(Class applicableFor) + { + this.applicableFor = applicableFor; + } + @Override public Object[] serialize(T object) { @@ -46,11 +58,10 @@ public T unserialize(Class objectClass, Object... args) throws Exce return null; } - @SuppressWarnings("unchecked") @Override public Class applicableFor() { - return (Class) Object.class; + return applicableFor; } @Override diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index bf6b4db..3477e6c 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -16,7 +16,7 @@ org.ugp.serialx - core + juss ${revision} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 45060e3..ef140db 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -19,7 +19,6 @@ import java.util.Map.Entry; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.JussSerializer; import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; @@ -28,10 +27,11 @@ import org.ugp.serialx.converters.DataParser.ParserRegistry; import org.ugp.serialx.converters.NullConverter; import org.ugp.serialx.converters.StringConverter; -import org.ugp.serialx.converters.VariableConverter; import org.ugp.serialx.json.converters.JsonCharacterConverter; import org.ugp.serialx.json.converters.JsonNumberConverter; import org.ugp.serialx.json.converters.JsonObjectConverter; +import org.ugp.serialx.juss.JussSerializer; +import org.ugp.serialx.juss.converters.VariableConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index 255591d..1807b9e 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -2,9 +2,9 @@ import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.ArrayConverter; -import org.ugp.serialx.converters.ObjectConverter; +import org.ugp.serialx.Utils; import org.ugp.serialx.json.JsonSerializer; +import org.ugp.serialx.juss.converters.ObjectConverter; import org.ugp.serialx.protocols.SerializationProtocol; /** @@ -21,7 +21,7 @@ public class JsonObjectConverter extends ObjectConverter public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) { if (arg.getClass().isArray()) - arg = new Scope(ArrayConverter.fromAmbiguous(arg)); + arg = new Scope(Utils.fromAmbiguousArray(arg)); SerializationProtocol prot = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args); diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index bc08a57..2c451bd 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -12,4 +12,12 @@ SerialX-juss SerialX support for Java Universal Serial Script data format, custom default format of SerialX! + + + + org.ugp.serialx + core + ${revision} + + \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java similarity index 94% rename from SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 7cb815e..fa667f3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,4 +1,4 @@ -package org.ugp.serialx; +package org.ugp.serialx.juss; import static org.ugp.serialx.Utils.Clone; import static org.ugp.serialx.Utils.InvokeStaticFunc; @@ -25,14 +25,26 @@ import java.util.Map; import java.util.Map.Entry; +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; import org.ugp.serialx.Utils.NULL; +import org.ugp.serialx.converters.BooleanConverter; +import org.ugp.serialx.converters.CharacterConverter; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.ObjectConverter; -import org.ugp.serialx.converters.imports.ImportConverter; -import org.ugp.serialx.converters.imports.ImportConverter.Imports; +import org.ugp.serialx.converters.NullConverter; +import org.ugp.serialx.converters.NumberConverter; +import org.ugp.serialx.converters.SerializableBase64Converter; +import org.ugp.serialx.converters.StringConverter; import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.juss.converters.ArrayConverter; +import org.ugp.serialx.juss.converters.ImportConverter; +import org.ugp.serialx.juss.converters.ObjectConverter; +import org.ugp.serialx.juss.converters.OperationGroups; +import org.ugp.serialx.juss.converters.VariableConverter; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; /** @@ -43,7 +55,6 @@ * * @since 1.3.2 */ -//TODO: Separate to SerialX-juss together with parsers and stuff @SuppressWarnings("serial") public class JussSerializer extends Serializer implements ImportsProvider { @@ -52,7 +63,7 @@ public class JussSerializer extends Serializer implements ImportsProvider * * @since 1.3.2 */ - public static final ParserRegistry JUSS_PARSERS = DataParser.REGISTRY.clone(); + public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. @@ -185,7 +196,7 @@ public ParserRegistry getParsers() public Imports getImports() { if (imports == null) - imports = ImportConverter.IMPORTS.clone(); + imports = ImportsProvider.IMPORTS.clone(); return imports; } @@ -439,7 +450,7 @@ else if (notString && ch == '/' && i < len-1 && line.charAt(i+1) == '*') { if (notString) { - if (ch == '{' || ch == '[') + if (ch | ' ') == '{' || ch == '[') brackets++; else if (ch == '}' || ch == ']') { @@ -486,10 +497,10 @@ else if (ch == '}' || ch == ']') if (parent == null) getImports().removeImportsOf(this); - else - for (Map.Entry ent : parent.varEntrySet()) - if (variables().get(ent.getKey()) == ent.getValue()) - variables().remove(ent.getKey());//TODO: Prevent neccesity of scope parent inheritance. +// else +// for (Map.Entry ent : parent.varEntrySet()) +// if (variables().get(ent.getKey()) == ent.getValue()) +// variables().remove(ent.getKey());//TODO: Prevent neccesity of scope parent inheritance. return (S) this; } @@ -538,7 +549,7 @@ else if (notString && ch >= 9 && ch <= 13) { /*if (notString) { - if (ch == '{' || ch == '[') + if (ch | ' ') == '{' || ch == '[') brackets++; else if (ch == '}' || ch == ']') { @@ -614,9 +625,9 @@ protected List splitAndParse(String formattedStr, int offset, Object... } //add = 1; } - else if (ch == '{' || ch == '[') + else if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') { if (brackets > 0) brackets--; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java similarity index 64% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 45e756a..7ba3db7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -1,13 +1,11 @@ -package org.ugp.serialx.converters; +package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.ToClasses; +import static org.ugp.serialx.Utils.castArray; +import static org.ugp.serialx.Utils.fromAmbiguousArray; import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.splitValues; -import java.lang.reflect.Array; -import java.util.Arrays; - -import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.converters.DataConverter; /** * This converter is capable of converting primitive arrays. @@ -101,13 +99,13 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. if (args.length > 2) args[2] = index + 1; - Object[] elms = fromAmbiguous(obj); + Object[] elms = fromAmbiguousArray(obj); StringBuilder sb = new StringBuilder(); for (int i = 0, length = elms.length, sizeEndl = 10000; i < length; i++) { CharSequence str = myHomeRegistry.toString(elms[i], args); char ch = str.charAt(0); - if (ch == '{' || ch == '[') + if ((ch | ' ') == '{') sb.append("("+str+")"); else sb.append(str); @@ -146,60 +144,4 @@ public String[] tokenize(String str) { return splitValues(str, ' '); } - - /** - * @param sourceArray | Array to cast! - * @param toType | Type to cast array in to! - * - * @return Array object casted in to required type! - * - * @since 1.3.2 - */ - public static Object castArray(Object[] sourceArray, Class toType) - { - int len = sourceArray.length; - Object arr = Array.newInstance(ToClasses(toType)[0], len); - for (int i = 0; i < len; i++) - Array.set(arr, i, sourceArray[i]); - return arr; - } - - /** - * @param arr1 | Object one that might be array! - * @param arr2 | Object two that might be array! - * - * @return New array consisting of array 1 and array 2! - * - * @throws IllegalArgumentException if object one is not an array! - * - * @since 1.3.2 - */ - public static Object[] mergeArrays(Object arr1, Object arr2) - { - Object[] array1 = fromAmbiguous(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguous(arr2) : new Object[] {arr2}; - Object[] result = Arrays.copyOf(array1, array1.length + array2.length); - System.arraycopy(array2, 0, result, array1.length, array2.length); - return result; - } - - /** - * @param array | Object that might be array! - * - * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! - * - * @throws IllegalArgumentException if the specified object is not an array! - * - * @since 1.3.2 - */ - public static Object[] fromAmbiguous(Object array) - { - if (array instanceof Object[]) - return (Object[]) array; - - int len = Array.getLength(array); - Object[] arr = new Object[len]; - for (int i = 0; i < len; i++) - arr[i] = Array.get(array, i); - return arr; - } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java new file mode 100644 index 0000000..9812b9d --- /dev/null +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java @@ -0,0 +1,79 @@ +package org.ugp.serialx.juss.converters; + +import org.ugp.serialx.LogProvider; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.imports.Import; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.converters.imports.ImportsProvider.Imports; + +/** + * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! + * Parsing example: import java.util.ArrayList will add temporary {@link Import} of java.util.ArrayList or java.lang.String => Word will import java.lang.String as Word! + * Imports will be converted to string just by calling toString!
+ *
+ * This parser requires additional parser arg at index 0 of type {@link ImportsProvider} that will obtain managed imports! This arg is required during both parsing and converting! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ImportConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (args.length > 0 && args[0] instanceof ImportsProvider) + { + Imports imports = ((ImportsProvider) args[0]).getImports(); + int index; + if (str.startsWith("import ")) + { + try + { + if ((str = str.substring(7).trim()).indexOf("=>") > -1) + return parse(myHomeRegistry, str, args); + imports.add(new Import(imports.forName(str), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str + " because there is no such a class!", e); + } + return VOID; + } + else if ((index = (str = str.trim()).indexOf("=>")) > -1) + { + try + { + imports.add(new Import(imports.forName(str.substring(0, index).trim()), str.substring(index+2).trim(), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str.substring(0, index).trim() + " because there is no such a class!", e); + } + catch (Exception e2) + { + LogProvider.instance.logErr(e2.getMessage(), e2); + } + return VOID; + } + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) + { + return obj.toString(); + } + return CONTINUE; + } + + @Override + public String getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Import of " + ((Import) objToDescribe).getCls() + " as " + ((Import) objToDescribe).getClsAlias(); + } +} \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java new file mode 100644 index 0000000..57c222f --- /dev/null +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -0,0 +1,199 @@ +package org.ugp.serialx.juss.converters; + +import static org.ugp.serialx.Utils.indexOfNotInObj; + +import java.io.IOException; +import java.io.Serializable; +import java.io.StringReader; +import java.util.Arrays; +import java.util.Base64; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Registry; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.ProtocolConverter; +import org.ugp.serialx.converters.SerializableBase64Converter; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.juss.JussSerializer; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; + +/** + * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! + * This is also responsible for {@link Scope}! + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + +
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
+
+ This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
+ This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
+ * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class ObjectConverter extends ProtocolConverter +{ + /** + * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) + */ + protected boolean useBase64IfCan = false; + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) + { + int len; + if ((len = str.length()) > 0) + { + boolean hasOp, hasCls = false; + if ((hasOp = (str.charAt(0) | ' ') == '{') && (hasCls = (str.charAt(--len) | ' ') == '}')) // Unwrap if wrapped in {} + len = (str = str.substring(1, len).trim()).length(); + + Class objClass; + int chI; + if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) < 0 || (++chI < len && str.charAt(chI) == ':')) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) // Is protocol expr + return parse(myHomeRegistry, objClass, str, compilerArgs); + + if (hasOp && hasCls) //Is scope + { + Serializer scope; + try //Create desired new empty instance of scope/serializer + { + if (compilerArgs.length > 0 && compilerArgs[0] instanceof Serializer) + { + if (compilerArgs.length > 4 && compilerArgs[4] instanceof Class && Serializer.class.isAssignableFrom((Class) compilerArgs[4])) + scope = ((Serializer) compilerArgs[0]).emptyClone((Class) compilerArgs[4], (GenericScope) compilerArgs[0]); + else + scope = ((Serializer) compilerArgs[0]).emptyClone(); + } + else + scope = getPreferredSerializer(); + } + catch (Exception e) + { + scope = getPreferredSerializer(); + } + + //TODO: Prevent neccesity of scope parent inheritance. + return str.isEmpty() ? scope : ((Serializer) scope/*.inheritParent()*/).LoadFrom(new StringReader(str), compilerArgs); + } + } + return CONTINUE; + } + + @Override + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + { + return toString(myHomeRegistry, arg, null, args); + } + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param preferedProtocol | Protocol to use preferably. + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) + { + if (arg instanceof Scope) + { + Serializer serializer; + try + { + if (arg instanceof Serializer) + serializer = (Serializer) arg; + else if (args.length > 0 && args[0] instanceof Serializer) + (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) arg); + else + serializer = getPreferredSerializer(); + } + catch (Exception e) + { + serializer = getPreferredSerializer(); + } + + if (serializer instanceof JussSerializer) + ((JussSerializer) serializer).setGenerateComments(args.length > 5 && args[5] instanceof Boolean && (boolean) args[5]); + + try + { + if (args.length < 4) + args = Arrays.copyOf(args, 4); + else + args = args.clone(); + args[2] = 0; + args[3] = serializer.getProtocols(); + + StringBuilder sb = new StringBuilder(); + GenericScope parent; + if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) + sb.append(ImportsProvider.getAliasFor(serializer, getClass()) + " "); + return serializer.SerializeAsSubscope(sb, args); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + return super.toString(myHomeRegistry, arg, preferedProtocol, args); + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + if (obj instanceof Scope && ((Scope) obj).isEmpty()) + return "Empty scope!"; + else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) + return "Multiline char sequence!"; + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); + } + + /** + * @return Serializer that is supposed to be used for serializing sub-scopes if there is no other option. This should never return null! + * + * @since 1.3.5 + */ + public Serializer getPreferredSerializer() + { + return new JussSerializer(); + } +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java similarity index 96% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java index 021a6b0..f4d2d3a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java @@ -1,4 +1,4 @@ -package org.ugp.serialx.converters; +package org.ugp.serialx.juss.converters; import static org.ugp.serialx.Utils.Instantiate; import static org.ugp.serialx.Utils.InvokeStaticFunc; @@ -15,12 +15,16 @@ import java.util.Base64; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.JussSerializer; import org.ugp.serialx.LogProvider; import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.SerializableBase64Converter; import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.juss.JussSerializer; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -60,7 +64,7 @@ * * @since 1.3.0 */ -public class ObjectConverter implements DataConverter +public class ObjectConverterOld implements DataConverter { /** * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. @@ -70,7 +74,7 @@ public class ObjectConverter implements DataConverter * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
* Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverterOld}) */ protected boolean useBase64IfCan = false; @@ -86,7 +90,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile { if (objectClass != null) //TODO: Preferably separate this to ProtocolConverter { - if (objectClass == IsSelectorScope.class) + if (objectClass == IsSelectorScope.class) { StringBuilder sb = new StringBuilder(str); sb.setCharAt(str.indexOf(' '), '='); @@ -420,7 +424,7 @@ public void setUseBase64IfCan(boolean useBase64IfCan) * @param args | Parser args to get protocol from! * * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
- * Note: This is mainly used by {@link ObjectConverter}! + * Note: This is mainly used by {@link ObjectConverterOld}! * * @since 1.3.5 */ @@ -451,10 +455,9 @@ public static Class getProtocolExprClass(String str, Object[] compilerArgs) for (char ch; i < len; i++) if ((ch = str.charAt(i)) == ' ' || ch == ':') break; - try { - Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ObjectConverter.class.getClassLoader()); + Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ObjectConverterOld.class.getClassLoader()); if (cls != null) return cls; for (char ch; i < len; i++) @@ -511,7 +514,7 @@ public static char[] secondarySubscopeWrappers() } /** - * Used internally by {@link ObjectConverter}!
+ * Used internally by {@link ObjectConverterOld}!
* Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: * * shortenedSelectorLikeScope {

@@ -523,5 +526,5 @@ public static char[] secondarySubscopeWrappers() * * @since 1.3.0 */ - protected static class IsSelectorScope {}; + public static class IsSelectorScope {}; } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java similarity index 96% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 8374a40..005603d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -1,4 +1,4 @@ -package org.ugp.serialx.converters; +package org.ugp.serialx.juss.converters; import static org.ugp.serialx.Utils.isOneOf; @@ -8,6 +8,7 @@ import org.ugp.serialx.LogProvider; import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataParser; /** * This parser provides ability to use expression groups that can define order of expression evaluation and compilation! @@ -122,9 +123,9 @@ public static int indexOfOpening(CharSequence str, int from, char... openings) quote++; else if (quote % 2 == 0) { - if (ch == '{' || ch == '[') + if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') { if (brackets > 0) brackets--; @@ -158,9 +159,9 @@ public static int indexOfClosing(CharSequence str, int from, char[] openings, ch quote++; else if (quote % 2 == 0) { - if (ch == '{' || ch == '[') + if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') { if (brackets > 0) brackets--; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java similarity index 95% rename from SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 7d51f0b..a7374d4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,4 +1,4 @@ -package org.ugp.serialx.converters; +package org.ugp.serialx.juss.converters; import static org.ugp.serialx.Utils.Clone; import static org.ugp.serialx.Utils.contains; @@ -15,6 +15,7 @@ import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.Utils.NULL; +import org.ugp.serialx.converters.DataConverter; /** * This converter is capable of converting {@link Map.Entry} and reading variables from {@link Scope} via "$"! @@ -194,9 +195,9 @@ public static boolean isVarAssignment(CharSequence s) return false; else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) return true; - else if (ch == '{' || ch == '[') + else if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') if (brackets > 0) brackets--; } @@ -205,6 +206,13 @@ else if (ch == '}' || ch == ']') return false; } +// public static V getValueOf(GenericScope scope, K... pathToScope) +// { +// +// if (scope.containsVariable(pathToScope[0])) +// return scope.getGenericScope(pathToScope); +// } + /** * @param varName | Name of variable. * @param varValue | Value of variable. diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index ab17c54..c05f137 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -11,7 +11,7 @@ import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; -import org.ugp.serialx.converters.ArrayConverter; +import org.ugp.serialx.Utils; import org.ugp.serialx.converters.DataParser; /** @@ -64,7 +64,7 @@ protected Object eval(ParserRegistry registryForParsers, String expr, Object... cof1 = cofs.get(index = index < 0 ? 0 : index); if (cof1 instanceof String) - cof1 = registryForParsers.parse(cof1.toString().trim(), i > 0, new Class[] {getClass(), ArrayConverter.class}, argsForParsers); + cof1 = registryForParsers.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers); cof1 = cof1 instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1; cof2 = cofs.remove(index + 1); @@ -186,14 +186,14 @@ public static Object add(Object cof, Object cof2) } if (cof.getClass().isArray()) - return ArrayConverter.mergeArrays(cof, cof2); + return Utils.mergeArrays(cof, cof2); if (cof instanceof Collection) { if (cof2 instanceof Collection) ((Collection) cof).addAll(((Collection) cof2)); else if (cof2.getClass().isArray()) - ((Collection) cof).addAll(Arrays.asList(ArrayConverter.fromAmbiguous(cof2))); + ((Collection) cof).addAll(Arrays.asList(Utils.fromAmbiguousArray(cof2))); else ((Collection) cof).add(cof2); return cof; @@ -206,7 +206,7 @@ else if (cof2.getClass().isArray()) else if (cof2 instanceof Collection) ((Scope) cof).addAll((Collection) cof2); else if (cof2.getClass().isArray()) - ((Scope) cof).addAll(ArrayConverter.fromAmbiguous(cof2)); + ((Scope) cof).addAll(Utils.fromAmbiguousArray(cof2)); else ((Scope) cof).add(cof2); return cof; @@ -241,7 +241,7 @@ public static Object sub(Object cof, Object cof2) if (cof2 instanceof Collection) ((Collection) cof).removeAll(((Collection) cof2)); else if (cof2.getClass().isArray()) - ((Collection) cof).removeAll(Arrays.asList(ArrayConverter.fromAmbiguous(cof2))); + ((Collection) cof).removeAll(Arrays.asList(Utils.fromAmbiguousArray(cof2))); else ((Collection) cof).remove(cof2); return cof; @@ -370,9 +370,9 @@ public static List[] getTerms(String str, char... oprs) char ch = str.charAt(i); if (ch == '\"') quote++; - else if (ch == '{' || ch == '[') + else if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') brackets--; if (type == 1 || quote % 2 == 0 && brackets == 0) @@ -420,9 +420,9 @@ public static boolean isExpression(CharSequence str, char... operators) quote++; else if (quote % 2 == 0) { - if (ch == '{' || ch == '[') + if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') brackets--; else if (brackets == 0) { diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 9925c3a..102e19c 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -73,9 +73,9 @@ public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfiti char ch = str.charAt(i); if (ch == '\"') quote++; - else if (ch == '{' || ch == '[') + else if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') brackets--; else if (quote % 2 == 0 && brackets == 0) { @@ -110,9 +110,9 @@ public static int indexOfOne(CharSequence str, int from, char oneChar) char ch = str.charAt(from); if (ch == '\"') quote++; - else if (ch == '{' || ch == '[') + else if ((ch | ' ') == '{') brackets++; - else if (ch == '}' || ch == ']') + else if ((ch | ' ') == '}') brackets--; else if (quote % 2 == 0 && brackets == 0 && ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) return from; From 5ddb3a4cdcf875354306c8b70a8ce93a3bf7206b Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 5 Dec 2023 18:32:20 +0100 Subject: [PATCH 09/75] some micro optimalizations i < len-1 -> i > 0 --- .../serialx/converters/ProtocolConverter.java | 9 +++++---- .../ugp/serialx/protocols/AutoProtocol.java | 1 + .../org/ugp/serialx/juss/JussSerializer.java | 6 +++--- .../juss/converters/ArrayConverter.java | 19 ++++++++++--------- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index bb04719..e671dfd 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -205,10 +205,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ args = args.clone(); for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) { - if (args.length > 2) - args[2] = index + 1; - sb.append(myHomeRegistry.toString(objArgs[i], args)); - if (i < objArgs.length-1) + if (i > 0) if (sb.length() > sizeEndl) { sb.append('\n'); @@ -218,6 +215,10 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ } else sb.append(' '); + + if (args.length > 2) + args[2] = index + 1; + sb.append(myHomeRegistry.toString(objArgs[i], args)); } args[4] = oldObjectClass; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java index cb717f7..3180c27 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java @@ -4,6 +4,7 @@ import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import org.ugp.serialx.Scope; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index fa667f3..d1136a4 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -323,15 +323,15 @@ else if (args[1] instanceof Integer) for (i = 0; i < valuesLen; i++) //Values { + if (i > 0) + source.append('\n'); + Object obj = objs.get(i); CharSequence serialized = reg.toString(obj, args); appandVal(source, serialized, obj, tabs, i >= valuesLen-1); if (generateComments && (!(obj instanceof Scope) || ((Scope) obj).isEmpty())) GenerateComment(source, reg, obj); - - if (i < valuesLen-1) - source.append('\n'); } if (source instanceof Flushable) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 7ba3db7..e7f6f45 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -103,23 +103,24 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. StringBuilder sb = new StringBuilder(); for (int i = 0, length = elms.length, sizeEndl = 10000; i < length; i++) { - CharSequence str = myHomeRegistry.toString(elms[i], args); - char ch = str.charAt(0); - if ((ch | ' ') == '{') - sb.append("("+str+")"); - else - sb.append(str); - - if (i < length-1) + if (i > 0) if (sb.length() > sizeEndl) { - sb.append('\n'); + sb.append('\n'); for (int j = 0; j < tabs+1; j++) sb.append('\t'); sizeEndl += 10000; } else sb.append(' '); + + CharSequence str = myHomeRegistry.toString(elms[i], args); + char ch = str.charAt(0); + if ((ch | ' ') == '{') + sb.append('(').append(str).append(')'); + else + sb.append(str); + } return index > 0 ? sb.insert(0, '(').append(')') : sb; } From f01159af84dcad3e2beec4a37b3864b5c053030f Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 5 Dec 2023 19:06:16 +0100 Subject: [PATCH 10/75] same as previous --- .../src/main/java/org/ugp/serialx/juss/JussSerializer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index d1136a4..7a4b2f0 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -316,7 +316,7 @@ else if (args[1] instanceof Integer) if (generateComments && (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty())) GenerateComment(source, reg, var); - if (i++ < varLen-1 || valuesLen > 0) + if (++i < varLen || valuesLen > 0) source.append('\n'); } } @@ -325,10 +325,10 @@ else if (args[1] instanceof Integer) { if (i > 0) source.append('\n'); - + Object obj = objs.get(i); CharSequence serialized = reg.toString(obj, args); - + appandVal(source, serialized, obj, tabs, i >= valuesLen-1); if (generateComments && (!(obj instanceof Scope) || ((Scope) obj).isEmpty())) GenerateComment(source, reg, obj); From 5a31fd674e9bb281b2a608fa6deeb74094567fcf Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 27 Dec 2023 23:54:16 +0100 Subject: [PATCH 11/75] no javafx, and stop importing it... --- .../src/main/java/org/ugp/serialx/json/JsonSerializer.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index ef140db..bf12831 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -35,8 +35,6 @@ import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import javafx.beans.binding.When; - /** * This is implementation of {@link JussSerializer} for serializing in Json! * It should generate and work with .json files! From f4d8b06a4f95a31b00813a9613aa0155ef855229 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Thu, 28 Dec 2023 11:45:03 +0100 Subject: [PATCH 12/75] ... --- .../src/main/java/org/ugp/serialx/protocols/AutoProtocol.java | 1 - 1 file changed, 1 deletion(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java index 3180c27..cb717f7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java @@ -4,7 +4,6 @@ import java.beans.PropertyDescriptor; import java.util.ArrayList; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; import org.ugp.serialx.Scope; From 8ceb5de46dac577b9f5039dfb3f4c0364faa2354 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 31 Dec 2023 23:31:41 +0100 Subject: [PATCH 13/75] fixing bug with ArrayConverter affecting other objects, better default logErr, finishing and testing refactor of ObjectConverter, adding tests to GeneralExample --- .../java/org/ugp/serialx/LogProvider.java | 12 +- .../src/main/java/org/ugp/serialx/Utils.java | 2 +- .../ugp/serialx/converters/DataParser.java | 4 +- .../serialx/converters/ProtocolConverter.java | 38 +- .../ugp/serialx/protocols/MapProtocol.java | 2 +- .../ugp/serialx/protocols/ScopeProtocol.java | 2 +- .../protocols/SerializationProtocol.java | 8 +- .../UniversalObjectInstantiationProtocol.java | 4 +- .../converters/DebugParserRegistry.java | 4 +- .../org/ugp/serialx/juss/JussSerializer.java | 2 +- .../juss/converters/ArrayConverter.java | 3 + .../juss/converters/ObjectConverter.java | 9 +- .../juss/converters/ObjectConverterOld.java | 530 ------------------ 13 files changed, 69 insertions(+), 551 deletions(-) delete mode 100644 SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java index 5ab4f08..f9eadae 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java @@ -40,7 +40,17 @@ public void logErr(Object obj, Throwable ex) throw new RuntimeException(obj.toString()); throw new RuntimeException(ex); } - System.err.println(obj); + + try + { + StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; + String callerName = caller.getClassName(); + System.err.println(callerName.substring(callerName.lastIndexOf('.')+1) + "#" + caller.getMethodName() + ": " + obj); + } + catch (Exception e) + { + System.err.println(obj); + } } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 11e1025..f4052a3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -426,7 +426,7 @@ else if (objs[i] instanceof Class) } for (int i = 0; i < classes.length; i++) - classes[i] = objs[i].getClass(); + classes[i] = objs[i] == null ? Object.class : objs[i].getClass(); return classes; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index b53fb83..78b52ef 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -260,7 +260,7 @@ public CharSequence toString(Object obj, Object... args) } } - LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); return null; } @@ -316,7 +316,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign if (returnAsStringIfNotFound) return str; - LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); return null; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index e671dfd..7dd56f0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -23,7 +23,6 @@ /** * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! - * This is also responsible for {@link Scope}! * Its case sensitive! *
*
@@ -48,14 +47,15 @@ 10 -
+ Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
+
This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
* This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
* * @author PETO * - * @since 1.3.0 + * @since 1.3.0 (separated from ObjectConverter since 1.3.7) */ public class ProtocolConverter implements DataConverter { @@ -71,6 +71,8 @@ public class ProtocolConverter implements DataConverter */ protected boolean useBase64IfCan = false; + protected boolean allowStaticMemberInvocation = false; + @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) { @@ -99,11 +101,11 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile */ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String str, Object... compilerArgs) { - if (objClass == IsSelectorScope.class) + if (objClass == IsSelectorScope.class) //Handle css-like selector scope to variable assignment { StringBuilder sb = new StringBuilder(str); sb.setCharAt(str.indexOf(' '), '='); - return myHomeRegistry.parse(sb.toString(), compilerArgs); + return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ObjectConverter and VariableConverter are present... } if (compilerArgs.length < 5) @@ -116,6 +118,12 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String if (!isOneOf(args[0].charAt(0), '{', '[') && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation { String memberName = args[0].substring(nameIndex + 2); + if (!isAllowStaticMemberInvocation()) + { + LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because this feature is disabled by default for security reasons!", null); + return null; + } + if (args.length > 1) return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); @@ -274,6 +282,26 @@ public void setUseBase64IfCan(boolean useBase64IfCan) this.useBase64IfCan = useBase64IfCan; } + /** + * @return True if invocation of static members (:: operator) is allowed (false by default)! + * + * @since 1.3.7 + */ + public boolean isAllowStaticMemberInvocation() + { + return allowStaticMemberInvocation; + } + + /** + * @param allowStaticMemberInvocation | Enable/disable the invocation of static members (:: operator) (false by default)! + * + * @since 1.3.7 + */ + public void setAllowStaticMemberInvocation(boolean allowStaticMemberInvocation) + { + this.allowStaticMemberInvocation = allowStaticMemberInvocation; + } + /** * @param obj | Object to get protocol for! * @param mode | Protocol mode! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java index 54fab5a..eacd7ee 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java @@ -37,7 +37,7 @@ public Map unserialize(Class> obje { boolean isFromScope = args.length == 1 && args[0] instanceof GenericScope; if (args.length % 2 != 0 && !isFromScope) - LogProvider.instance.logErr(getClass().getSimpleName() + ": Some variables have no values, this is not good!", null); + LogProvider.instance.logErr("Some variables have no values, this is not good!", null); if (objectClass.isInterface()) objectClass = (Class>) HashMap.class; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java index d1c8a69..aae4ce0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java @@ -23,7 +23,7 @@ public Object[] serialize(GenericScope object) throws Exception { if (object.getClass() != Scope.class) return new Object[] {object.castTo(Scope.class)}; - throw new UnsupportedOperationException(getClass().getSimpleName() + ": You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!"); + throw new UnsupportedOperationException("You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!"); } @Override diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 7aab546..13248f3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -30,7 +30,7 @@ public abstract class SerializationProtocol * * @since 1.3.0 */ - public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(new UniversalObjectInstantiationProtocol<>(Object.class), new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); + public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); /** * This mode is for protocols that are used for serialization only! @@ -191,7 +191,7 @@ public static Object[] serializeObj(ProtocolRegistry registry, O object) thr SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE); if (prot == null) { - LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); + LogProvider.instance.logErr("Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); return null; } return prot.serialize(object); @@ -231,7 +231,7 @@ public static O unserializeObj(ProtocolRegistry registry, Class SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE); if (prot == null) { - LogProvider.instance.logErr(SerializationProtocol.class.getSimpleName() + ": Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); + LogProvider.instance.logErr("Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); return null; } return (O) prot.unserialize(objectClass, args); @@ -294,7 +294,7 @@ public ProtocolRegistry clone() public void add(int index, SerializationProtocol element) { if (GetProtocolFor(element.applicableFor()) != null && element.applicableFor() != Object.class) - LogProvider.instance.logErr(getClass().getSimpleName() + ": Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null); + LogProvider.instance.logErr("Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null); addDuplicatively(index, element); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java index b941f2b..045401e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java @@ -33,7 +33,7 @@ public UniversalObjectInstantiationProtocol(Class applicableFor) @Override public Object[] serialize(T object) { - throw new UnsupportedOperationException(getClass().getSimpleName() + ": This protocol is only for reading! It cant serialize " + object); + throw new UnsupportedOperationException("This protocol is only for reading! It cant serialize " + object); } @SuppressWarnings("unchecked") @@ -54,7 +54,7 @@ public T unserialize(Class objectClass, Object... args) throws Exce catch (IllegalArgumentException e) {} } - LogProvider.instance.logErr(getClass().getSimpleName() + ": Unable to call create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); + LogProvider.instance.logErr("Unable to create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); return null; } diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java index 2ad0472..bc300ca 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java @@ -94,7 +94,7 @@ public CharSequence toString(Object obj, Object... args) { } } - LogProvider.instance.logErr(DataConverter.class.getSimpleName() + ": Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); return null; } @@ -149,7 +149,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign if (returnAsStringIfNotFound) return str; - LogProvider.instance.logErr(DataParser.class.getSimpleName() + ": Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); return null; } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 7a4b2f0..71b414d 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -63,7 +63,7 @@ public class JussSerializer extends Serializer implements ImportsProvider * * @since 1.3.2 */ - public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new ImportConverter(), new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index e7f6f45..0849c5f 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -97,7 +97,10 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. tabs = (int) args[1]; if (args.length > 2) + { + args = args.clone(); //Necessary for preventing this from affecting other objects and arrays... args[2] = index + 1; + } Object[] elms = fromAmbiguousArray(obj); StringBuilder sb = new StringBuilder(); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 57c222f..00c7c42 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -42,12 +42,17 @@ ArrayList 2 4 6 new ArrayList<>(Arrays.asList(2, 4, 6)) + + { ... } + new Scope( ... ) + java.lang.Math::max 10 5 10 -
+ Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
+
This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
* This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
@@ -107,6 +112,8 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile } //TODO: Prevent neccesity of scope parent inheritance. + compilerArgs = compilerArgs.clone(); + compilerArgs[0] = false; //No extra formating... return str.isEmpty() ? scope : ((Serializer) scope/*.inheritParent()*/).LoadFrom(new StringReader(str), compilerArgs); } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java deleted file mode 100644 index f4d2d3a..0000000 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverterOld.java +++ /dev/null @@ -1,530 +0,0 @@ -package org.ugp.serialx.juss.converters; - -import static org.ugp.serialx.Utils.Instantiate; -import static org.ugp.serialx.Utils.InvokeStaticFunc; -import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.isOneOf; -import static org.ugp.serialx.Utils.splitValues; - -import java.io.IOException; -import java.io.Serializable; -import java.io.StringReader; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Registry; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.SerializableBase64Converter; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.juss.JussSerializer; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; - -/** - * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! - * This is also responsible for {@link Scope}! - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - * - - - - - - - - - - - - - -
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
-
- This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
- This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
- * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
- * - * @author PETO - * - * @since 1.3.0 - */ -public class ObjectConverterOld implements DataConverter -{ - /** - * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. - * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverterOld}) - */ - protected boolean useBase64IfCan = false; - - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) - { - Class objectClass = null, oldObjectClass; - boolean hasOp, hasCls = false; - char ch; - - if (str.length() > 0 && ((hasOp = (ch = str.charAt(0)) == '{' || ch == '[') && (hasCls = (ch = str.charAt(str.length()-1)) == '}' || ch == ']') /*|| containsNotInObj(str, ' ')*/ || (objectClass = getProtocolExprClass(str, compilerArgs)) != null)) - { - if (objectClass != null) //TODO: Preferably separate this to ProtocolConverter - { - if (objectClass == IsSelectorScope.class) - { - StringBuilder sb = new StringBuilder(str); - sb.setCharAt(str.indexOf(' '), '='); - return myHomeRegistry.parse(sb.toString(), compilerArgs); - } - else - { - if (compilerArgs.length < 5) - compilerArgs = Arrays.copyOf(compilerArgs, 5); - oldObjectClass = (Class) compilerArgs[4]; - compilerArgs[4] = objectClass; - } - - String[] args = splitValues(str = str.trim(), ' '); - if (!isOneOf(args[0].charAt(0), '{', '[') && args[0].contains("::")) - { - String[] clsAttr = args[0].split("::"); - if (clsAttr.length > 1) - { - if (args.length > 1) - try - { - Object rtrn = InvokeStaticFunc(objectClass, clsAttr[1], parseAll(myHomeRegistry, args, 1, true, compilerArgs)); - compilerArgs[4] = oldObjectClass; - return rtrn; - } - catch (InvocationTargetException e) - { - LogProvider.instance.logErr("Exception while calling method \"" + clsAttr[1] + "\":", e); - e.printStackTrace(); - } - else - try - { - compilerArgs[4] = oldObjectClass; - return clsAttr[1].equals("class") ? objectClass : clsAttr[1].equals("new") ? Instantiate(objectClass) : objectClass.getField(clsAttr[1]).get(null); - } - catch (NoSuchFieldException e) - { - try - { - Object rtrn = InvokeStaticFunc(objectClass, clsAttr[1], parseAll(myHomeRegistry, args, 1, true, compilerArgs)); - compilerArgs[4] = oldObjectClass; - return rtrn; - } - catch (InvocationTargetException e2) - { - LogProvider.instance.logErr("Exception while calling method \"" + clsAttr[1] + "\":", e2); - e.printStackTrace(); - } - } - catch (Exception e) - { - LogProvider.instance.logErr("Unable to obtain value of field \"" + clsAttr[1] + "\" in class \"" + objectClass.getSimpleName() + "\" because:", e); - e.printStackTrace(); - } - /*catch (ClassNotFoundException e) - { - LogProvider.instance.logErr("Unable to invoke \"" + args[0].split("::")[1] + "\" because class \"" + args[0].split("::")[0] + "\" was not found!"); - } */ - } - } - else - { - try - { - if ((ch = str.charAt(str.length()-1)) == ';' || ch == ',') - throw new ClassNotFoundException(); - - Object[] objArgs = parseAll(myHomeRegistry, args, 1, true, compilerArgs); - if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objectClass)) - return objArgs[0]; - compilerArgs[4] = oldObjectClass; - return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, objectClass, objArgs); - - /*Object obj; - if (objArgs.length == 1 && objArgs[0] instanceof Scope) - { - Scope scope = (Scope) objArgs[0]; - if ((obj = p.unserialize(objectClass, scope.toValArray())) != null) - return obj; - return p.unserialize(objectClass, scope); - } - else - { - if ((obj = p.unserialize(objectClass, objArgs)) != null) - return obj; - return p.unserialize(objectClass, new Scope(objArgs)); - }*/ - } - catch (Exception e) - { - LogProvider.instance.logErr("Exception while unserializing instance of \"" + objectClass.getName() + "\":", e); - e.printStackTrace(); - } - } - compilerArgs[4] = oldObjectClass; - } - else - { - Serializer scope; - try - { - if (compilerArgs.length > 0 && compilerArgs[0] instanceof Serializer) - { - if (compilerArgs.length > 4 && compilerArgs[4] instanceof Class && Serializer.class.isAssignableFrom((Class) compilerArgs[4])) - scope = ((Serializer) compilerArgs[0]).emptyClone((Class) compilerArgs[4], (GenericScope) compilerArgs[0]); - else - scope = ((Serializer) compilerArgs[0]).emptyClone(); - } - else - scope = getPreferredSerializer(); - } - catch (Exception e) - { - scope = getPreferredSerializer(); - } - - if (indexOfNotInObj(str, '=', ':', ';', ',') > -1) - { - compilerArgs = compilerArgs.clone(); - compilerArgs[0] = false; - //TODO: Prevent neccesity of scope parent inheritance. - return ((Serializer) scope.inheritParent()).LoadFrom(new StringReader(str), compilerArgs); - } - - if (hasOp && hasCls) - { - str = str.substring(1, str.length()-1).trim(); - if (str.isEmpty()) - return scope; - - int index; - if ((index = indexOfNotInObj(str, '=', ';', ',')) > -1 && (index >= str.length()-1 || str.charAt(index+1) != ':') || (objectClass = getProtocolExprClass(str, compilerArgs)) == null || objectClass == IsSelectorScope.class) - { - compilerArgs = compilerArgs.clone(); - compilerArgs[0] = false; - return ((Serializer) scope.inheritParent()).LoadFrom(new StringReader(str), compilerArgs); - } - - if (objectClass != null && indexOfNotInObj(str, "::") > -1) - return myHomeRegistry.parse(str, compilerArgs); - return parse(myHomeRegistry, str, compilerArgs); - } - else if (str.split(" ").length > 1) - { - LogProvider.instance.logErr("Unable to unserialize \"" + str + "\"! Possible reason of this is absence of comma or semicolon, try to insert them into empty spaces!", null); - return null; - } - } - LogProvider.instance.logErr("Unable to unserialize \"" + str + "\" because there is no such class or source string is corrupted!", null); - return null; - } - return CONTINUE; - } - - @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) - { - return toString(myHomeRegistry, arg, null, args); - } - - /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! - * @param obj | Object to convert into string! - * @param preferedProtocol | Protocol to use preferably. - * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! - * - * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) - { - if (arg == null) - return CONTINUE; - - if (useBase64IfCan && arg instanceof Serializable) - return CONTINUE; - - if (arg instanceof Scope) - { - Serializer serializer; - try - { - if (arg instanceof Serializer) - serializer = (Serializer) arg; - else if (args.length > 0 && args[0] instanceof Serializer) - (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) arg); - else - serializer = getPreferredSerializer(); - } - catch (Exception e) - { - serializer = getPreferredSerializer(); - } - - if (serializer instanceof JussSerializer) - ((JussSerializer) serializer).setGenerateComments(args.length > 5 && args[5] instanceof Boolean && (boolean) args[5]); - - try - { - if (args.length < 4) - args = Arrays.copyOf(args, 4); - else - args = args.clone(); - args[2] = 0; - args[3] = serializer.getProtocols(); - - StringBuilder sb = new StringBuilder(); - GenericScope parent; - if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) - sb.append(ImportsProvider.getAliasFor(serializer, getClass()) + " "); - return serializer.SerializeAsSubscope(sb, args); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - else //TODO: Preferably separate this to ProtocolConverter - { - if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) - { - Object[] objArgs; - Class oldObjectClass = null; - try - { - int tabs = 0, index = 0; - if (args.length > 1 && args[1] instanceof Integer) - tabs = (int) args[1]; - - if (args.length > 2 && args[2] instanceof Integer) - index = (int) args[2]; - - if (args.length < 5) - args = Arrays.copyOf(args, 5); - oldObjectClass = (Class) args[4]; - args[4] = arg.getClass();; - - objArgs = preferedProtocol.serialize(arg); - StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, arg.getClass()) + (objArgs.length <= 0 ? "" : " ")); - - args = args.clone(); - for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) - { - if (args.length > 2) - args[2] = index + 1; - sb.append(myHomeRegistry.toString(objArgs[i], args)); - if (i < objArgs.length-1) - if (sb.length() > sizeEndl) - { - sb.append('\n'); - for (int j = 0; j < tabs+1; j++) - sb.append('\t'); - sizeEndl += 10000; - } - else - sb.append(' '); - } - - args[4] = oldObjectClass; - return index > 0 && objArgs.length > 0 ? sb.insert(0, '{').append('}') : sb; - } - catch (Exception e) - { - LogProvider.instance.logErr("Exception while serializing instance of \"" + arg.getClass().getName() + "\":", e); - e.printStackTrace(); - } - args[4] = oldObjectClass; - } - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - if (obj instanceof Scope && ((Scope) obj).isEmpty()) - return "Empty scope!"; - else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) - return "Multiline char sequence!"; - return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); - } - - /** - * @return Serializer that is supposed to be used for serializing sub-scopes if there is no other option. - * - * @since 1.3.5 - */ - public Serializer getPreferredSerializer() - { - return new JussSerializer(); - } - - /** - * @return True if program is forced to use {@link Base64} serialization on {@link Serializable} objects. - * This might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.3.5 - */ - public boolean isUseBase64IfCan() - { - return useBase64IfCan; - } - - /** - * @param useBase64IfCan | Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. - * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.3.5 - */ - public void setUseBase64IfCan(boolean useBase64IfCan) - { - this.useBase64IfCan = useBase64IfCan; - } - - /** - * @param obj | Object to get protocol for! - * @param mode | Protocol mode! - * @param args | Parser args to get protocol from! - * - * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
- * Note: This is mainly used by {@link ObjectConverterOld}! - * - * @since 1.3.5 - */ - public static SerializationProtocol getProtocolFor(Object obj, byte mode, Object[] args) - { - if (args.length > 3) - { - if (args[3] instanceof ProtocolRegistry) - return ((ProtocolRegistry) args[3]).GetProtocolFor(obj, mode); - else if (args[3] instanceof SerializationProtocol) - return (SerializationProtocol) args[3]; - } - - return SerializationProtocol.REGISTRY.GetProtocolFor(obj, mode); - } - - /** - * @param str | String to check protocol class for! - * - * @return Class of the protocol or null if inserted statement is not protocol expression! - * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! - * - * @since 1.3.0 - */ - public static Class getProtocolExprClass(String str, Object[] compilerArgs) - { - int i = 0, len = str.length(); - for (char ch; i < len; i++) - if ((ch = str.charAt(i)) == ' ' || ch == ':') - break; - try - { - Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ObjectConverterOld.class.getClassLoader()); - if (cls != null) - return cls; - for (char ch; i < len; i++) - { - if ((ch = str.charAt(i)) > 32) - if (ch == '{' || ch == '[') - return IsSelectorScope.class; - else - return null; - } - } - catch (ClassNotFoundException e) - {} - return null; - } - - /** - * @param registry | Registry to use! - * @param strs | Source strings to parse using suitable parser from registry. - * @param from | Start index to begin from! - * @param trim | If true, all strings will be trimed before parsing! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Array of parsed objects, each parsed using {@link DataParser#parseObj(String, Object...)} - * - * @since 1.3.0 - */ - public static Object[] parseAll(ParserRegistry registry, String strs[], int from, boolean trim, Object... args) - { - Object[] objs = new Object[strs.length-from]; - for (int i = 0; from < strs.length; from++, i++) - objs[i] = registry.parse(trim ? strs[from].trim() : strs[from], args); - return objs; - } - - /** - * @return Array with 2 preferred sub-scope wrapping chars that are used during serialization by default. { and } - * - * @since 1.3.5 - */ - public static char[] primarySubscopeWrappers() - { - return new char[] {'{', '}'}; - } - - /** - * @return Array with 2 secondary sub-scope wrapping char. [ and ] - * - * @since 1.3.5 - */ - public static char[] secondarySubscopeWrappers() - { - return new char[] {'[', ']'}; - } - - /** - * Used internally by {@link ObjectConverterOld}!
- * Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: - * - * shortenedSelectorLikeScope {

- * //stuff... - * }; - *
- * - * @author PETO - * - * @since 1.3.0 - */ - public static class IsSelectorScope {}; -} \ No newline at end of file From 402a77d3d1654b6bf55271d650fb0317f595e0ba Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 20 Feb 2024 17:20:06 +0100 Subject: [PATCH 14/75] begining refactor of VarConver... --- .../java/org/ugp/serialx/GenericScope.java | 18 ++++---- .../src/main/java/org/ugp/serialx/Utils.java | 4 +- .../juss/converters/VariableConverter.java | 45 ++++++++++++++++--- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 3ca29a7..3a59a44 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -286,6 +286,7 @@ public V get(KeyT variableKey, V defaultValue) * @return Value of variable at given path. If no path is given (length is 0) then this {@link GenericScope} will be returned.
* If 1 path argument is given then this behaves similarly to {@link GenericScope#get(Object)}.
* if 2+ path arguments are given then it will search the sub-scopes and return first match value. For example:
+ * In either way, if there is no suitable result then null will be returned!
* Consider this scope tree:
*
 	 * 
@@ -361,10 +362,7 @@ public  V get(KeyT variableKey, Class cls, V defaultValue) th
 	 */
 	public boolean containsVariable(KeyT variableKey) 
 	{
-		for (Map.Entry ent : varEntrySet())
-			if (ent.getKey().equals(variableKey))
-				return true;
-		return false;
+		return variables().containsKey(variableKey);
 	}
 	
 	/**
@@ -792,9 +790,9 @@ public boolean isEmpty()
 	 * 
 	 * @since 1.2.0
 	 */
-	public GenericScope getParent()
+	public > T getParent()
 	{
-		return getParent(1);	
+		return (T) getParent(1);	
 	}
 	
 	/**
@@ -806,15 +804,15 @@ public boolean isEmpty()
 	 * 
 	 * @since 1.3.2
 	 */
-	public GenericScope getParent(int depth)
+	public > T getParent(int depth)
 	{
 		if (depth < 1)
-			return this;
+			return (T) this;
 		
 		GenericScope parentsParent;
 		if (depth == 1 || parent == null || (parentsParent = parent.getParent(--depth)) == null)
-			return parent;
-		return parentsParent;
+			return (T) parent;
+		return (T) parentsParent;
 	}
 	
 	/**
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
index f4052a3..ef5a592 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
@@ -855,7 +855,7 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO
 	 *
 	 * @since 1.2.2
 	 */
-	public static final class NULL
+	public static final class NULL //TODO: REMOVE!!!!
 	{
 		public static Object toOopNull(Object obj)
 		{
@@ -871,7 +871,7 @@ public boolean equals(Object obj)
 		@Override
 		public String toString() 
 		{
-			return "null";
+			return "NULL";
 		}
 	}
 }
\ No newline at end of file
diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
index a7374d4..8a20384 100644
--- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
+++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
@@ -14,8 +14,10 @@
 import org.ugp.serialx.GenericScope;
 import org.ugp.serialx.LogProvider;
 import org.ugp.serialx.Scope;
+import org.ugp.serialx.Utils;
 import org.ugp.serialx.Utils.NULL;
 import org.ugp.serialx.converters.DataConverter;
+import org.ugp.serialx.converters.DataParser;
 
 /**
  * This converter is capable of converting {@link Map.Entry} and reading variables from {@link Scope} via "$"!
@@ -70,7 +72,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args)
 				
 				if (enrty.length > 1 && !objString.isEmpty())
 				{
-					obj = NULL.toOopNull(myHomeRegistry.parse(objString, args));
+					obj = myHomeRegistry.parse(objString, args);
 				}
 
 				for (int i = 0; i < enrty.length-1; i++)
@@ -105,12 +107,38 @@ else if (obj == VOID)
 			}
 			else if (arg.charAt(0) == '$' && !contains(arg, ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '='))
 			{
+//				Object obj; 
+//				if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1)
+//				{
+//					Object[] path = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.');
+//					GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(path, 0, path.length-1)); //TODO: Prevent neccesity of scope parent inheritance.
+//					obj = sc == null ? null : sc.variables().get(path[path.length-1]);
+//					/*if (sc == null || !sc.containsVariable(tree[tree.length-1]))
+//						LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/
+//				}
+//				else
+//				{
+//					String str = fastReplace(fastReplace(arg, "::new", ""), "::class", "");
+//					/*if (!scope.containsVariable(str))
+//						LogProvider.instance.logErr("Variable \"" + str + "\" was not declared! Defaulting to null!");*/
+//					obj = scope.variables().get(str);
+//				}
+				
 				Object obj; 
 				if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1)
 				{
-					Object[] tree = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.');
-					GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(tree, 0, tree.length-1)); //TODO: Prevent neccesity of scope parent inheritance.
-					obj = sc == null ? null : sc.variables().get(tree[tree.length-1]);
+					Object[] path = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.');
+					if ((obj = scope.get(path)) == null && !scope.variables().containsKey(path[0]))
+					{
+						for (GenericScope parent = scope.getParent(); parent != null; parent = parent.getParent())
+							if (parent.variables().containsKey(path[0]))
+							{
+								obj = parent.get(path);
+								break;
+							}
+					}
+						
+//					GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(path, 0, path.length-1)); //TODO: Prevent neccesity of scope parent inheritance.
 					/*if (sc == null || !sc.containsVariable(tree[tree.length-1]))
 						LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/
 				}
@@ -119,9 +147,16 @@ else if (arg.charAt(0) == '$' && !contains(arg, ' ', '+', '-', '*', '/', '%', '>
 					String str = fastReplace(fastReplace(arg, "::new", ""), "::class", "");
 					/*if (!scope.containsVariable(str))
 						LogProvider.instance.logErr("Variable \"" + str + "\" was not declared! Defaulting to null!");*/
-					obj = scope.variables().get(str);
+					if ((obj = scope.variables().getOrDefault(str, VOID)) == VOID)
+					{
+						for (GenericScope parent = scope.getParent(); parent != null; parent = parent.getParent())
+							if ((obj = parent.variables().getOrDefault(str, VOID)) != VOID)
+								break;
+					}
 				}
 
+				if (obj == null || obj == VOID) // Was not found...
+					return null;
 				return arg.endsWith("::class") ? obj.getClass() : arg.endsWith("::new") ? Clone(obj) : obj;
 			}
 		}

From c80d378551229bc280d17d7083c440e8d189c86c Mon Sep 17 00:00:00 2001
From: Programmer001 
Date: Sat, 2 Mar 2024 19:59:26 +0100
Subject: [PATCH 15/75] Refactoring VariableConverter, splitting it to
 VariableParser and it. Some formatings

---
 .../java/org/ugp/serialx/GenericScope.java    |   7 +-
 .../src/main/java/org/ugp/serialx/Scope.java  |  22 ++--
 .../src/main/java/org/ugp/serialx/Utils.java  |   2 +
 .../ugp/serialx/converters/DataParser.java    |   2 +-
 .../serialx/converters/VariableParser.java    | 103 ++++++++++++++++++
 .../org/ugp/serialx/juss/JussSerializer.java  |   4 +-
 .../juss/converters/VariableConverter.java    |  81 +++-----------
 7 files changed, 137 insertions(+), 84 deletions(-)
 create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java

diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java
index 3a59a44..8f243dd 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java
@@ -267,7 +267,7 @@ public  V get(KeyT variableKey)
 	 * @param variableKey | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Value of variable with name or defaultValue if there is no such a one!
+	 * @return Value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * 
 	 * @since 1.2.5
 	 */
@@ -337,7 +337,7 @@ public  V get(KeyT... pathToValue)
 	 * @param cls | Default value to return.
 	 * @param defaultValue | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations.
 	 * 
-	 * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one!
+	 * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one or given key contains null!
 	 * 
 	 * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)}
 	 * 
@@ -792,7 +792,7 @@ public boolean isEmpty()
 	 */
 	public > T getParent()
 	{
-		return (T) getParent(1);	
+		return getParent(1);	
 	}
 	
 	/**
@@ -804,6 +804,7 @@ public boolean isEmpty()
 	 * 
 	 * @since 1.3.2
 	 */
+	@SuppressWarnings("unchecked")
 	public > T getParent(int depth)
 	{
 		if (depth < 1)
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
index c0defa6..757dc98 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
@@ -159,7 +159,7 @@ public byte getByte(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Byte value of variable with name or defaultValue if there is no such a one!
+	 * @return Byte value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -186,7 +186,7 @@ public short getShort(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Byte value of variable with name or defaultValue if there is no such a one!
+	 * @return Byte value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -213,7 +213,7 @@ public int getInt(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Int value of variable with name or defaultValue if there is no such a one!
+	 * @return Int value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -240,7 +240,7 @@ public int getLong(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Long value of variable with name or defaultValue if there is no such a one!
+	 * @return Long value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -267,7 +267,7 @@ public float getFloat(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Float value of variable with name or defaultValue if there is no such a one!
+	 * @return Float value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -294,7 +294,7 @@ public double getDouble(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Double value of variable with name or defaultValue if there is no such a one!
+	 * @return Double value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -328,7 +328,7 @@ public String getString(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return String value of variable with name or defaultValue if there is no such a one!
+	 * @return String value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * String will be also parsed from any object using {@link Object#toString()}!
 	 * 
 	 * @since 1.2.5
@@ -355,7 +355,7 @@ public char getChar(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Char value of variable with name or defaultValue if there is no such a one!
+	 * @return Char value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -389,7 +389,7 @@ public boolean getBool(String variableName)
 	 * @param variableName | Variables name.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Boolean value of variable with name or defaultValue if there is no such a one!
+	 * @return Boolean value of variable with name or defaultValue if there is no such a one or given key contains null!
 	 * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible!
 	 * 
 	 * @since 1.2.5
@@ -715,7 +715,7 @@ public  T toObjectOf(String variableWithscope, Class objClass) throws Exce
 	 * @param objClass | Object of class to create.
 	 * @param defaultValue | Default value to return.
 	 * 
-	 * @return Value of variable with name or defaultValue if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}!
+	 * @return Value of variable with name or defaultValue if there is no such a one or given key contains null! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}!
 	 * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass.
 	 * 
 	 * @see Serializer#PROTOCOL_REGISTRY
@@ -736,7 +736,7 @@ public  T toObjectOf(String variableWithscope, Class objClass, T defaultVa
 	 * @param defaultValue | Default value to return.
 	 * @param protocolsToUse | Registry of protocols to use.
 	 * 
-	 * @return Value of variable with name or defaultValue if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}!
+	 * @return Value of variable with name or defaultValue if there is no such a one or given key contains null! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}!
 	 * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass.
 	 * 
 	 * @see Serializer#PROTOCOL_REGISTRY
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
index ef5a592..830ba29 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java
@@ -854,6 +854,8 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO
 	 * @author PETO
 	 *
 	 * @since 1.2.2
+	 * 
+	 * @deprecated (in 1.3.7) NO LONGER NEEDED, DO NOT USE THIS! You were never supposed to...
 	 */
 	public static final class NULL //TODO: REMOVE!!!!
 	{
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
index 78b52ef..7498674 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
@@ -41,7 +41,7 @@ public interface DataParser
 	 * 
 	 * @since 1.3.0
 	 */
-	public static final ParserRegistry REGISTRY = new ParserRegistry(/* new OperationGroups(), new VariableConverter(),*/ new StringConverter(), /*new ObjectConverter(),*/ /*TODO: remove new ArrayConverter(),*/ new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
+	public static final ParserRegistry REGISTRY = new ParserRegistry(new VariableParser(), new StringConverter(), new ProtocolConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter());
 	
 	/**
 	 * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)!
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java
new file mode 100644
index 0000000..2e40c57
--- /dev/null
+++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java
@@ -0,0 +1,103 @@
+package org.ugp.serialx.converters;
+
+import static org.ugp.serialx.Utils.Clone;
+import static org.ugp.serialx.Utils.contains;
+import static org.ugp.serialx.Utils.splitValues;
+
+import org.ugp.serialx.GenericScope;
+import org.ugp.serialx.Registry;
+import org.ugp.serialx.Scope;
+import org.ugp.serialx.Serializer;
+
+/**
+ * This parser is capable of reading variables from {@link GenericScope} by using "$"!
+ * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0!
+ * Its case sensitive!
+ * Exact outputs of this converter are based on inserted scope! + * + * @author PETO + * + * @since 1.3.7 + */ +public class VariableParser implements DataParser +{ + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (args.length > 0 && str.length() > 0 && args[0] instanceof GenericScope) + { + return parse(myHomeRegistry, str, (GenericScope) args[0], args); + } + return CONTINUE; + } + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param str | Source string (preferably with some variables to read)! + * @param scope | Source scope to read from, can't be null! + * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. + * + * @return Value of variable read from scope is str was suitable. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) + { + if (str.charAt(0) == '$' && !contains(str, ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) + { + + boolean clsModif = str.endsWith("::class"), newModif = false; // Handle modifiers... + if (clsModif) + str = str.substring(0, str.length()-7); + else if (newModif = str.endsWith("::new")) + str = str.substring(0, str.length()-5); + + Object obj = null; + if ((str = str.substring(1)).indexOf('.') > -1) + { + Object[] path = splitValues(str, '.'); + int iLast = path.length-1; + + backlook: do + { + Object sc = scope.variables().getOrDefault(path[0], VOID); + if (sc instanceof GenericScope) // The first one has to be scope! + { + for (int i = 1; i < iLast; i++) // Subscope/forward lookup... + if (!((sc = ((GenericScope) sc).get(path[i])) instanceof GenericScope)) + { + // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[i] + "\" is not a scope but " + sc + "!", null); + break backlook; + } + + obj = ((GenericScope) sc).variables().get(path[iLast]); + break; + } + + if (sc != VOID) // = variable was defined in parent but it is not a scope, it means we want to break cos we can't deref that = treat the path as invalid (undefined)... + { + // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[0] + "\" is not a scope but " + sc + "!", null); + break; + } + } + while ((scope = scope.getParent()) != null); + } + else + { + do + { + if ((obj = scope.variables().getOrDefault(str, VOID)) != VOID) + break; + } + while ((scope = scope.getParent()) != null); + } + + if (obj == null || obj == VOID) // When was not found... + return null; + return clsModif ? obj.getClass() : newModif ? Clone(obj, scope instanceof Serializer ? ((Serializer) scope).getParsers() : DataParser.REGISTRY, new Object[] {}, new Scope()) : obj; + } + return CONTINUE; + } +} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 71b414d..0871155 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -701,13 +701,13 @@ public T cloneOf(String variableName) * @param variable | Variable to clone! * @param defaultValue | Default value to return. * - * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one! + * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! *

* Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! * * @since 1.3.2 */ - public T cloneOf(String variableName , T defaultValue) + public T cloneOf(String variableName, T defaultValue) { T obj = get(variableName , defaultValue); if (obj == defaultValue) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 8a20384..e09c3b3 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,6 +1,5 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.Clone; import static org.ugp.serialx.Utils.contains; import static org.ugp.serialx.Utils.fastReplace; import static org.ugp.serialx.Utils.multilpy; @@ -13,23 +12,20 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Utils; -import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.VariableParser; /** - * This converter is capable of converting {@link Map.Entry} and reading variables from {@link Scope} via "$"! - * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... argument! - * Its case insensitive!
+ * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using "$"! + * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0! + * Its case sensitive!
* Exact outputs of this converter are based on inserted scope! * * @author PETO * * @since 1.3.0 */ -public class VariableConverter implements DataConverter +public class VariableConverter extends VariableParser implements DataConverter { protected boolean jsonStyle; @@ -57,7 +53,7 @@ public VariableConverter(boolean jsonStyle) @SuppressWarnings("unchecked") @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) { @@ -69,7 +65,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) Object obj = null; String objString = enrty[enrty.length-1]; - + if (enrty.length > 1 && !objString.isEmpty()) { obj = myHomeRegistry.parse(objString, args); @@ -93,7 +89,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) sc.put(genericVar ? myHomeRegistry.parse(tree[tree.length-1], true, null, args) : tree[tree.length-1], obj); } else - LogProvider.instance.logErr("Variable \"" + tree[tree.length-2] +"\" was not declared as scope in its scope so variable \"" + tree[tree.length-1] +"\" cant be set to \"" + obj + "\"!", null); + LogProvider.instance.logErr("Variable \"" + tree[tree.length-2] + "\" was not declared as scope in its scope so variable \"" + tree[tree.length-1] +"\" cant be set to \"" + obj + "\"!", null); } else if (obj == VOID) scope.variables().remove(enrty[i]); @@ -101,64 +97,13 @@ else if (obj == VOID) scope.put(genericVar ? myHomeRegistry.parse(enrty[i], true, null, args) : enrty[i], obj); } } + if (arg.charAt(0) == '$') return obj; return VOID; } - else if (arg.charAt(0) == '$' && !contains(arg, ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) - { -// Object obj; -// if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1) -// { -// Object[] path = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.'); -// GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(path, 0, path.length-1)); //TODO: Prevent neccesity of scope parent inheritance. -// obj = sc == null ? null : sc.variables().get(path[path.length-1]); -// /*if (sc == null || !sc.containsVariable(tree[tree.length-1])) -// LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/ -// } -// else -// { -// String str = fastReplace(fastReplace(arg, "::new", ""), "::class", ""); -// /*if (!scope.containsVariable(str)) -// LogProvider.instance.logErr("Variable \"" + str + "\" was not declared! Defaulting to null!");*/ -// obj = scope.variables().get(str); -// } - - Object obj; - if ((arg = fastReplace(arg, "$", "")).indexOf('.') > -1) - { - Object[] path = splitValues(fastReplace(fastReplace(arg, "::new", ""), "::class", ""), '.'); - if ((obj = scope.get(path)) == null && !scope.variables().containsKey(path[0])) - { - for (GenericScope parent = scope.getParent(); parent != null; parent = parent.getParent()) - if (parent.variables().containsKey(path[0])) - { - obj = parent.get(path); - break; - } - } - -// GenericScope sc = (GenericScope) scope.getGenericScope(Arrays.copyOfRange(path, 0, path.length-1)); //TODO: Prevent neccesity of scope parent inheritance. - /*if (sc == null || !sc.containsVariable(tree[tree.length-1])) - LogProvider.instance.logErr("Variable \"" + tree[tree.length-1] + "\" was not declared in \"" + arg.substring(0, arg.length() - tree[tree.length-1].length() - 1) + "\"! Defaulting to null!");*/ - } - else - { - String str = fastReplace(fastReplace(arg, "::new", ""), "::class", ""); - /*if (!scope.containsVariable(str)) - LogProvider.instance.logErr("Variable \"" + str + "\" was not declared! Defaulting to null!");*/ - if ((obj = scope.variables().getOrDefault(str, VOID)) == VOID) - { - for (GenericScope parent = scope.getParent(); parent != null; parent = parent.getParent()) - if ((obj = parent.variables().getOrDefault(str, VOID)) != VOID) - break; - } - } - - if (obj == null || obj == VOID) // Was not found... - return null; - return arg.endsWith("::class") ? obj.getClass() : arg.endsWith("::new") ? Clone(obj) : obj; - } + + return parse(myHomeRegistry, arg, scope, args); //Reading vars from scope... } return CONTINUE; } @@ -176,7 +121,9 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. boolean jsonStyle = isJsonStyle(), genericVar = false; Object key = (genericVar = !((key = var.getKey()) instanceof String)) ? myHomeRegistry.toString(key, args) : key, val = var.getValue(); - return new StringBuilder().append(jsonStyle && !genericVar ? "\""+key+"\"" : key).append(val instanceof Scope && !((Scope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")).append(myHomeRegistry.toString(val, args)); + return new StringBuilder().append(jsonStyle && !genericVar ? "\""+key+"\"" : key) + .append(val instanceof GenericScope && !((GenericScope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")) + .append(myHomeRegistry.toString(val, args)); } return CONTINUE; } From 269d20fb9a1f0c32b9bcbefceb0f0c870d5c74bc Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 19 Mar 2024 07:52:26 +0100 Subject: [PATCH 16/75] refactoring variable converter, adding access member op --- .../java/org/ugp/serialx/GenericScope.java | 4 +- .../src/main/java/org/ugp/serialx/Scope.java | 2 +- .../src/main/java/org/ugp/serialx/Utils.java | 11 ++- .../serialx/converters/ProtocolConverter.java | 3 +- .../serialx/converters/VariableParser.java | 51 ++++++---- .../juss/converters/VariableConverter.java | 97 ++++++++++++------- 6 files changed, 105 insertions(+), 63 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 8f243dd..778c47d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -267,7 +267,7 @@ public V get(KeyT variableKey) * @param variableKey | Variables name. * @param defaultValue | Default value to return. * - * @return Value of variable with name or defaultValue if there is no such a one or given key contains null! + * @return Value of variable with name or defaultValue if there is no such a one (or given key contains null)! * * @since 1.2.5 */ @@ -337,7 +337,7 @@ public V get(KeyT... pathToValue) * @param cls | Default value to return. * @param defaultValue | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. * - * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one or given key contains null! + * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one (or given key contains null)! * * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)} * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index 757dc98..eba21de 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -514,7 +514,7 @@ else if (obj instanceof CharSequence) */ public String getString(int valueIndex) { - return String.valueOf(get(valueIndex)); + return String.valueOf((Object) get(valueIndex)); } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 830ba29..e59b8ff 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -218,7 +218,7 @@ public static Object InvokeFunc(Object obj, Class objCls, String name, Class< */ public static T Clone(T obj) { - return Clone(obj, DataParser.REGISTRY, new Object[] {}, new Scope()); + return Clone(obj, DataParser.REGISTRY, new Object[0], new Scope()); } /** @@ -458,8 +458,8 @@ public static StringBuilder multilpy(char ch, int times) */ public static StringBuilder multilpy(CharSequence str, int times) { - StringBuilder sb = new StringBuilder(str); - while (times-- > 1) + StringBuilder sb = new StringBuilder(); + while (times-- > 0) sb.append(str); return sb; } @@ -503,7 +503,7 @@ public static String[] splitValues(String s, int limit, boolean splitAfterSingle * * @since 1.3.5 */ - public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) + public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) //TODO: This bs is terribly broken! Idk what I was doing back then but its not doing what I would assume at all... { if (splitter.length <= 0 || limit == 1) return new String[] {s}; @@ -727,9 +727,12 @@ public static boolean isOneOf(int ch, char... chars) public static boolean contains(CharSequence str, char... oneOf) { if (oneOf.length == 1) + { for (int i = 0, len = str.length(); i < len; i++) if (str.charAt(i) == oneOf[0]) return true; + return false; + } for (int i = 0, len = str.length(); i < len; i++) if (isOneOf(str.charAt(i), oneOf)) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 7dd56f0..c41079c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -2,7 +2,6 @@ import static org.ugp.serialx.Utils.Instantiate; import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.isOneOf; import static org.ugp.serialx.Utils.splitValues; import java.io.Serializable; @@ -115,7 +114,7 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String String[] args = splitValues(str, ' '); int nameIndex; - if (!isOneOf(args[0].charAt(0), '{', '[') && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation + if ((args[0].charAt(0) | ' ') != '{' && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation { String memberName = args[0].substring(nameIndex + 2); if (!isAllowStaticMemberInvocation()) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 2e40c57..947e52e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -11,7 +11,8 @@ /** * This parser is capable of reading variables from {@link GenericScope} by using "$"! - * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0! + * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0!
+ * It also manages access member operator also known as separator ".". * Its case sensitive!
* Exact outputs of this converter are based on inserted scope! * @@ -31,10 +32,27 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } return CONTINUE; } + + /** + * @param source | Source object to get value of the member from (may or may not be null). Source should not be modified! + * @param member | Name/key of the member to get. + * + * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
+ * Note: This method is meant to be overridden in order to add support for accessing multiple sources because by default it supports only {@link GenericScope} + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public Object getMemberOperator(Object source, Object member) + { + if (source instanceof GenericScope) + return ((GenericScope) source).variables().getOrDefault(member, VOID); + return null; + } /** * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! - * @param str | Source string (preferably with some variables to read)! + * @param str | Source string, should not be null or empty (preferably with some variables to read)! * @param scope | Source scope to read from, can't be null! * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. * @@ -42,12 +60,10 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * * @since 1.3.7 */ - @SuppressWarnings("unchecked") - protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) + protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) { - if (str.charAt(0) == '$' && !contains(str, ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) + if (str.charAt(0) == '$' && !contains(str = str.substring(1), ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) { - boolean clsModif = str.endsWith("::class"), newModif = false; // Handle modifiers... if (clsModif) str = str.substring(0, str.length()-7); @@ -55,30 +71,24 @@ else if (newModif = str.endsWith("::new")) str = str.substring(0, str.length()-5); Object obj = null; - if ((str = str.substring(1)).indexOf('.') > -1) + if (str.indexOf('.') > -1) { - Object[] path = splitValues(str, '.'); + String[] path = splitValues(str, '.'); int iLast = path.length-1; backlook: do { - Object sc = scope.variables().getOrDefault(path[0], VOID); - if (sc instanceof GenericScope) // The first one has to be scope! + Object sc; + if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... { - for (int i = 1; i < iLast; i++) // Subscope/forward lookup... - if (!((sc = ((GenericScope) sc).get(path[i])) instanceof GenericScope)) + for (int i = 1; i < iLast; i++) // Subscope/forward lookup (inner path only)... + if ((sc = getMemberOperator(sc, path[i])) == null || sc == VOID) { // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[i] + "\" is not a scope but " + sc + "!", null); break backlook; } - obj = ((GenericScope) sc).variables().get(path[iLast]); - break; - } - - if (sc != VOID) // = variable was defined in parent but it is not a scope, it means we want to break cos we can't deref that = treat the path as invalid (undefined)... - { - // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[0] + "\" is not a scope but " + sc + "!", null); + obj = getMemberOperator(sc, path[iLast]); break; } } @@ -96,8 +106,9 @@ else if (newModif = str.endsWith("::new")) if (obj == null || obj == VOID) // When was not found... return null; - return clsModif ? obj.getClass() : newModif ? Clone(obj, scope instanceof Serializer ? ((Serializer) scope).getParsers() : DataParser.REGISTRY, new Object[] {}, new Scope()) : obj; + return clsModif ? obj.getClass() : newModif ? Clone(obj, scope instanceof Serializer ? ((Serializer) scope).getParsers() : DataParser.REGISTRY, new Object[0], new Scope()) : obj; } + return CONTINUE; } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index e09c3b3..e5e8412 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,12 +1,10 @@ package org.ugp.serialx.juss.converters; import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.fastReplace; import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.Utils.splitValues; import java.util.AbstractMap; -import java.util.Arrays; import java.util.Map; import java.util.Map.Entry; @@ -17,13 +15,16 @@ /** * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using "$"! - * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0! + * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0!
+ * It manages assign operator = as well as access member operator also known as separator ".".
* Its case sensitive!
* Exact outputs of this converter are based on inserted scope! * * @author PETO * * @since 1.3.0 + * + * @see VariableParser */ public class VariableConverter extends VariableParser implements DataConverter { @@ -57,64 +58,68 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) { - GenericScope scope = (GenericScope) args[0]; - boolean genericVar = args.length > 4 && args[4] == GenericScope.class; + GenericScope scope = (GenericScope) args[0]; if (isVarAssignment(arg)) { - String[] enrty = splitValues(arg, 0, false, new char[] {'?'}, '=', ':'); - - Object obj = null; - String objString = enrty[enrty.length-1]; + boolean getValueModif = arg.charAt(0) == '$', genericVar = args.length > 4 && args[4] == GenericScope.class; + if (getValueModif) + arg = arg.substring(1); + + String vars[] = splitValues(arg, 0, false, new char[] {'?'}, '=', ':'), valStr; - if (enrty.length > 1 && !objString.isEmpty()) + Object val = null; + int iVal = vars.length-1; + if (vars.length > 1 && !(valStr = vars[iVal]).isEmpty()) { - obj = myHomeRegistry.parse(objString, args); + val = myHomeRegistry.parse(valStr, args); } - for (int i = 0; i < enrty.length-1; i++) + eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... { - if (!genericVar && contains(enrty[i] = enrty[i].trim(), ' ')) - LogProvider.instance.logErr("Variable name \"" + enrty[i] + "\" is invalid, blank characters are not allowed!", null); - else + String var = vars[i]; + if (!genericVar && contains(var, ' ')) + LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); + else if (var.indexOf('.') > -1) { - if ((enrty[i] = fastReplace(enrty[i], "$", "")).indexOf('.') > -1) + String[] path = splitValues(var, '.'); + int iLast = path.length-1, j = 0; + + backlook: do { - String[] tree = splitValues(enrty[i], '.'); - GenericScope sc = (GenericScope) scope.getGenericScope((Object[]) Arrays.copyOfRange(tree, 0, tree.length-1)); - if (sc != null) + Object sc; + if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... { - if (obj == VOID) - sc.variables().remove(enrty[i]); - else - sc.put(genericVar ? myHomeRegistry.parse(tree[tree.length-1], true, null, args) : tree[tree.length-1], obj); + for (j = 1; j < iLast; j++) // Subscope/forward lookup (inner path only)... + if ((sc = getMemberOperator(sc, path[j])) == null || sc == VOID) + break backlook; + + setMemberOperator(myHomeRegistry, sc, path[iLast], val, genericVar, args); + continue eachVar; } - else - LogProvider.instance.logErr("Variable \"" + tree[tree.length-2] + "\" was not declared as scope in its scope so variable \"" + tree[tree.length-1] +"\" cant be set to \"" + obj + "\"!", null); } - else if (obj == VOID) - scope.variables().remove(enrty[i]); - else - scope.put(genericVar ? myHomeRegistry.parse(enrty[i], true, null, args) : enrty[i], obj); + while ((scope = scope.getParent()) != null); + + LogProvider.instance.logErr("Path \"" + var + "\" cannot be set to \"" + val + "\" because \"" + path[j] + "\" is not a accessible or does not exist!", null); } + else + setMemberOperator(myHomeRegistry, scope, var, val, genericVar, args); } - if (arg.charAt(0) == '$') - return obj; - return VOID; + return getValueModif ? val : VOID; } return parse(myHomeRegistry, arg, scope, args); //Reading vars from scope... } + return CONTINUE; } - @SuppressWarnings("unchecked") @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { if (obj instanceof Entry) { - Entry var = (Entry) obj; + Entry var = (Entry) obj; int tabs = 0; if (args.length > 1 && args[1] instanceof Integer) tabs = (int) args[1]; @@ -136,6 +141,30 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDe return new StringBuilder(myHomeRegistry.getConverterFor(ent.getValue(), argsUsedConvert).getDescription(myHomeRegistry, ent.getValue(), argsUsedConvert)).append(" Stored by \"").append(ent.getKey()).append("\" variable!"); } + /** + * @param myHomeRegistry | {@link ParserRegistry} provided by caller, may or may not be used... + * @param source | Source object to set the value member. + * @param member | Name/key of the member to set. + * @param val | Value to set the member to. + * @param genericVar | If true, member is expected be generic (not only string) and further parsing is required, may or may not be used... + * @param args | Some additional args to be used in case of parsing that are provided by called, may or may not be used... + * + * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link VOID} should be returned! + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, String member, Object val, boolean genericVar, Object... args) + { + if (source instanceof GenericScope) + { + if (val == VOID) + return ((GenericScope) source).remove(member); + return ((GenericScope) source).put(genericVar ? myHomeRegistry.parse(member, true, null, args) : member, val); + } + return VOID; + } + /** * @return True if variables will be serialized using json style ("key" : value)! * From 11351a37ac285ad735bc3c57a108c2456cadf9d4 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 31 Mar 2024 00:11:01 +0100 Subject: [PATCH 17/75] Fixing splitValues, small fix JussSerializer#from, finishing refactor of VarParser and Converter + scope inheritance removed! --- .../main/java/org/ugp/serialx/Serializer.java | 28 ++++---- .../src/main/java/org/ugp/serialx/Utils.java | 64 ++++++++++++++----- .../serialx/converters/VariableParser.java | 11 ++-- .../org/ugp/serialx/juss/JussSerializer.java | 4 -- .../juss/converters/ObjectConverter.java | 3 +- .../juss/converters/VariableConverter.java | 30 +++++---- 6 files changed, 82 insertions(+), 58 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 9b5476b..9cc2103 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -28,13 +28,8 @@ import java.util.Map; import java.util.function.Function; -import org.ugp.serialx.converters.BooleanConverter; -import org.ugp.serialx.converters.CharacterConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.NullConverter; -import org.ugp.serialx.converters.NumberConverter; -import org.ugp.serialx.converters.SerializableBase64Converter; import org.ugp.serialx.converters.StringConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -56,7 +51,7 @@ public abstract class Serializer extends Scope * * @since 1.3.2 */ - public static final ParserRegistry COMMON_PARSERS = new ParserRegistry(new StringConverter(), /* TODO: new ProtocolConverter() */ new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + public static final ParserRegistry COMMON_PARSERS = DataParser.REGISTRY.clone(); protected ParserRegistry parsers; protected ProtocolRegistry protocols; @@ -1064,8 +1059,9 @@ Obtained serializer content (return) * - * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went very wrong during deserialization! * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * @throws RuntimeException in case of something went wrong during deserialization process and {@link LogProvider#isReThrowException()} is set to true! * * @since 1.3.5 */ @@ -1073,20 +1069,18 @@ public static Serializer from(Serializer newInstance, Object fromObj, String... { if (fromObj instanceof CharSequence) { - if (indexOfNotInObj((CharSequence) fromObj, "http") == 0) - try - { - return newInstance.LoadFrom(new URL(fromObj.toString()).openStream()); - } - catch (IOException e) - {} - try { - return newInstance.LoadFrom(new File(fromObj.toString())); + String fromStr; + if (indexOfNotInObj(fromStr = fromObj.toString(), "http") == 0) + return newInstance.LoadFrom(new URL(fromStr).openStream()); + return newInstance.LoadFrom(new File(fromStr)); } catch (Exception e) - {} + { + if (e instanceof RuntimeException) + throw e; + } return newInstance.LoadFrom((CharSequence) fromObj); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index e59b8ff..899f72c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -468,42 +468,65 @@ public static StringBuilder multilpy(CharSequence str, int times) * @param s | String to split and check some syntax. * @param splitter | Chars where string will be split! * - * @return String splitted after splitters. If there is more than one splitter in row, it will be taken as one whole! + * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med! * * @since 1.0.0 */ public static String[] splitValues(String s, char... splitter) { - return splitValues(s, 0, true, splitter); + return splitValues(s, 0, 2, splitter); } /** * @param s | String to split and check some syntax. * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! * @param splitter | Chars where string will be split! * - * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! * * @since 1.3.0 */ - public static String[] splitValues(String s, int limit, boolean splitAfterSingleCharOnly, char... splitter) + public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) { - return splitValues(s, limit, splitAfterSingleCharOnly, new char[0], splitter); + return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); } /** * @param s | String to split and check some syntax. * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param oneOrMore | If true, string will be splitted after one or more splitters in row, if false splitting will occur only after single splitter (this is similar to "+" in regex)! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! * @param splitter | Chars where string will be split! * - * @return String splitted after splitters according to arguments. If there is more than one splitter in row, it will be taken as one whole! + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! * * @since 1.3.5 */ - public static String[] splitValues(String s, int limit, boolean oneOrMore, char[] splitBreaks, char... splitter) //TODO: This bs is terribly broken! Idk what I was doing back then but its not doing what I would assume at all... + public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! + * + * @since 1.3.7 + */ + public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) { if (splitter.length <= 0 || limit == 1) return new String[] {s}; @@ -512,9 +535,9 @@ public static String[] splitValues(String s, int limit, boolean oneOrMore, char[ // return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); List result = new ArrayList<>(); - - int brackets = 0, quote = 0, lastIndex = 0; - for (int i = 0, count = 1, len = s.length(), oldCh = splitter[0]; i < len && (limit <= 0 || count < limit); i++) + + int brackets = 0, quote = 0, lastIndex = 0, len = s.length(); + for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) { char ch = s.charAt(i); if (ch == '"') @@ -528,10 +551,17 @@ public static String[] splitValues(String s, int limit, boolean oneOrMore, char[ break; } - if (brackets == 0 && oldCh != ch && isOneOf(ch, splitter) && (oneOrMore || (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + if (brackets == 0 && isOneOf(ch, splitter) && + (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) { - result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i).trim()); - count++; + String tok = s.substring(lastIndex, i).trim(); + if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) + { + result.add(tok); + lastIndex = i + 1; + + count++; + } } else if ((ch | ' ') == '{') brackets++; @@ -545,14 +575,14 @@ else if ((ch | ' ') == '}') } oldCh = ch; } - + if (brackets > 0) throw new IllegalArgumentException("Unclosed brackets in: " + s); else if (quote % 2 != 0) throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); else { - result.add(s.substring(lastIndex == 0 ? 0 : lastIndex + 1, s.length()).trim()); + result.add(s.substring(lastIndex, len).trim()); } return result.toArray(new String[0]); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 947e52e..ba99062 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -10,9 +10,9 @@ import org.ugp.serialx.Serializer; /** - * This parser is capable of reading variables from {@link GenericScope} by using "$"! - * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0!
- * It also manages access member operator also known as separator ".". + * This parser is capable of reading variables from {@link GenericScope} by using $!
+ * {@link VariableParser#parse(String, Object...)} requires one additional Scope argument in args... at index 0!
+ * It also manages access member operator also known as separator ".".
* Its case sensitive!
* Exact outputs of this converter are based on inserted scope! * @@ -71,9 +71,10 @@ else if (newModif = str.endsWith("::new")) str = str.substring(0, str.length()-5); Object obj = null; - if (str.indexOf('.') > -1) + int op0Index; + if ((op0Index = str.indexOf('.')) > -1) { - String[] path = splitValues(str, '.'); + String[] path = splitValues(str, op0Index, 0, 0, new char[0], '.'); int iLast = path.length-1; backlook: do diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 0871155..ccb1a71 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -497,10 +497,6 @@ else if (ch == '}' || ch == ']') if (parent == null) getImports().removeImportsOf(this); -// else -// for (Map.Entry ent : parent.varEntrySet()) -// if (variables().get(ent.getKey()) == ent.getValue()) -// variables().remove(ent.getKey());//TODO: Prevent neccesity of scope parent inheritance. return (S) this; } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 00c7c42..086ac55 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -111,10 +111,9 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile scope = getPreferredSerializer(); } - //TODO: Prevent neccesity of scope parent inheritance. compilerArgs = compilerArgs.clone(); compilerArgs[0] = false; //No extra formating... - return str.isEmpty() ? scope : ((Serializer) scope/*.inheritParent()*/).LoadFrom(new StringReader(str), compilerArgs); + return str.isEmpty() ? scope : scope.LoadFrom(new StringReader(str), compilerArgs); } } return CONTINUE; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index e5e8412..c3f57f5 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -14,8 +14,8 @@ import org.ugp.serialx.converters.VariableParser; /** - * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using "$"! - * {@link VariableConverter#parse(String, Object...)} required one additional Scope argument in args... at index 0!
+ * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using $!
+ * {@link VariableConverter#parse(String, Object...)} requires one additional Scope argument in args... at index 0!
* It manages assign operator = as well as access member operator also known as separator ".".
* Its case sensitive!
* Exact outputs of this converter are based on inserted scope! @@ -59,13 +59,17 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) { GenericScope scope = (GenericScope) args[0]; - if (isVarAssignment(arg)) + int op0Index; + if ((op0Index = isVarAssignment(arg)) > -1) { boolean getValueModif = arg.charAt(0) == '$', genericVar = args.length > 4 && args[4] == GenericScope.class; if (getValueModif) + { arg = arg.substring(1); + op0Index--; + } - String vars[] = splitValues(arg, 0, false, new char[] {'?'}, '=', ':'), valStr; + String vars[] = splitValues(arg, op0Index, 0, 1, new char[] {'?'}, '=', ':'), valStr; Object val = null; int iVal = vars.length-1; @@ -74,14 +78,14 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) val = myHomeRegistry.parse(valStr, args); } - eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... + eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... Yea this is not the prettiest code but it does the job and mainly it does it fast so shut up! { String var = vars[i]; - if (!genericVar && contains(var, ' ')) + if (!genericVar && contains(var, ' ')) LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); - else if (var.indexOf('.') > -1) + else if ((op0Index = var.indexOf('.')) > -1) { - String[] path = splitValues(var, '.'); + String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); int iLast = path.length-1, j = 0; backlook: do @@ -188,11 +192,11 @@ public void setJsonStyle(boolean jsonStyle) /** * @param s | CharSequence to search! * - * @return true if inserted expression is variable assignment expression such as variable = 4 otherwise false! + * @return Index of first assignment operator ('=' or ':') if inserted expression is variable assignment expression such as variable = 4, otherwise -1! * * @since 1.3.0 */ - public static boolean isVarAssignment(CharSequence s) + public static int isVarAssignment(CharSequence s) { for (int i = 0, brackets = 0, quote = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) { @@ -203,9 +207,9 @@ public static boolean isVarAssignment(CharSequence s) if (quote % 2 == 0) { if (ch == '?') - return false; + return -1; else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) - return true; + return i; else if ((ch | ' ') == '{') brackets++; else if ((ch | ' ') == '}') @@ -214,7 +218,7 @@ else if ((ch | ' ') == '}') } oldCh = ch; } - return false; + return -1; } // public static V getValueOf(GenericScope scope, K... pathToScope) From 22478c466004b7bd52ecb6b85c974ba154f92f8e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 2 Apr 2024 17:02:02 +0200 Subject: [PATCH 18/75] removing oop NULL like the colossal mistake it was... --- .../src/main/java/org/ugp/serialx/GenericScope.java | 10 +++------- .../src/main/java/org/ugp/serialx/Serializer.java | 6 +++--- SerialX-core/src/main/java/org/ugp/serialx/Utils.java | 2 +- .../java/org/ugp/serialx/converters/NullConverter.java | 4 +--- .../main/java/org/ugp/serialx/juss/JussSerializer.java | 3 +-- .../operators/ConditionalAssignmentOperators.java | 3 +-- 6 files changed, 10 insertions(+), 18 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 778c47d..7cec162 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -16,7 +16,6 @@ import java.util.function.Function; import java.util.function.Predicate; -import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -277,7 +276,7 @@ public V get(KeyT variableKey, V defaultValue) V obj = (V) variables().get(variableKey); if (obj == null) return defaultValue; - return obj instanceof NULL ? null : obj; + return obj; } /** @@ -388,8 +387,7 @@ public boolean containsIndependentValue(ValT value) @SuppressWarnings("unchecked") public V get(int valueIndex) { - V obj = (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); - return obj instanceof NULL ? null : obj; + return (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); } /** @@ -600,7 +598,6 @@ public GenericScope transform(Function trans, boolean incl try { Object obj = ent.getValue(); - obj = obj instanceof NULL ? null : obj; if (obj instanceof GenericScope && includeSubScopes) { GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); @@ -655,8 +652,7 @@ public List map(Function trans, boolean includeSubScopes) List fltVals = new ArrayList<>(); for (Object obj : this) try - { - obj = obj instanceof NULL ? null : obj; + { if (obj instanceof GenericScope && includeSubScopes) { GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 9cc2103..f677009 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -653,7 +653,7 @@ else if (multLineCom <= -1 && ch == '"') if (semicolon > index) { lineReader.close(); - return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, sb.toString(), this)); + return (T) DataParser.parseObj(DataParser.REGISTRY, sb.toString(), this); } if (multLineCom > -1 || com > -1) //Is comment @@ -722,7 +722,7 @@ else if (ch == '}' || ch == ']') else if (quote % 2 != 0) throw new IllegalArgumentException("Unclosed or missing quotes!"); else if (!(line = sb.toString()).isEmpty()) - return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, line, this)); + return (T) DataParser.parseObj(DataParser.REGISTRY, line, this); LogProvider.instance.logErr("Value with index " + index + " is out of bounds!"); return null; } @@ -808,7 +808,7 @@ else if (multLineCom <= -1 && ch == '"') int start = sb.indexOf("=", findIndex-fromIndexOrig); if (start <= -1) start = sb.indexOf(":", findIndex-fromIndexOrig); - return (T) NULL.toOopNull(DataParser.parseObj(DataParser.REGISTRY, sb.substring(start+1), this)); + return (T) DataParser.parseObj(DataParser.REGISTRY, sb.substring(start+1), this); } if (multLineCom > -1 || com > -1) //Is comment diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 899f72c..b22206d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -261,7 +261,7 @@ else if (obj.getClass() == String.class) { ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); - Object cln = NULL.toOopNull(parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs)); + Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); if (cln != null && cln != VOID) return (T) cln; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index 1d772b3..ae3c7af 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,7 +1,5 @@ package org.ugp.serialx.converters; -import org.ugp.serialx.Utils.NULL; - /** * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. * Its case insensitive! @@ -48,7 +46,7 @@ public Object parse(ParserRegistry registry, String str, Object... args) @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { - if (obj == null || obj instanceof NULL) + if (obj == null) return "null"; return CONTINUE; } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index ccb1a71..ea95a34 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -29,7 +29,6 @@ import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.BooleanConverter; import org.ugp.serialx.converters.CharacterConverter; import org.ugp.serialx.converters.DataConverter; @@ -676,7 +675,7 @@ else if (brackets > 0) */ protected Object parseObject(ParserRegistry registry, String str, Object... parserArgs) { - return NULL.toOopNull(registry.parse(str, parserArgs)); + return registry.parse(str, parserArgs); } /** diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 102e19c..57fc84c 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -3,7 +3,6 @@ import static org.ugp.serialx.Utils.indexOfNotInObj; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Utils.NULL; import org.ugp.serialx.converters.DataParser; /** @@ -45,7 +44,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) if ((index = str.indexOf("??")) > -1) { Object obj = myHomeRegistry.parse(str.substring(0, index).trim(), args); - if (obj != null && !(obj instanceof NULL)) + if (obj != null) return obj; String next = str.substring(index+2); From fa2b34ff5dda895060d16f07e31a998cfecfc158 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 2 Apr 2024 19:38:50 +0200 Subject: [PATCH 19/75] ... --- pom.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 00e37a7..de6c8cc 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ org.apache.maven.plugins maven-compiler-plugin + 3.10.1 ${java.version} @@ -63,7 +64,7 @@ eclipse - + org.codehaus.plexus plexus-compiler-eclipse @@ -72,7 +73,7 @@ org.eclipse.jdt ecj - 3.25.0 + 3.33.0 From 3fd9d39c1643777105c033ab2a1d0c8d8e410a58 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 2 Apr 2024 23:23:32 +0200 Subject: [PATCH 20/75] ... --- SerialX-core/src/main/java/org/ugp/serialx/Utils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index b22206d..51c40eb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -890,7 +890,7 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO * * @deprecated (in 1.3.7) NO LONGER NEEDED, DO NOT USE THIS! You were never supposed to... */ - public static final class NULL //TODO: REMOVE!!!! + public static final class NULL //TODO: REMOVE IN NEXT V!!!! { public static Object toOopNull(Object obj) { From 2faf39ada9a10e9d2113368bdf82bddf2824db1c Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 8 Apr 2024 08:10:55 +0200 Subject: [PATCH 21/75] important optimiz... --- .../src/main/java/org/ugp/serialx/Utils.java | 20 +++ .../serialx/converters/BooleanConverter.java | 25 +-- .../converters/CharacterConverter.java | 13 +- .../ugp/serialx/converters/NullConverter.java | 15 +- .../serialx/converters/NumberConverter.java | 145 +++++++++++++----- .../serialx/converters/StringConverter.java | 19 ++- 6 files changed, 167 insertions(+), 70 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 51c40eb..75326ee 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -770,6 +770,26 @@ public static boolean contains(CharSequence str, char... oneOf) return false; } + /** + * @param str | Source string to compare. + * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! + * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). + * @param to | The ending marking index, index where to end the comparing (exclusive, most likely str.length()) + * + * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
+ * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
+ * Also sufficient length of both strings is not checked so adjust from and to accordingly. + * + * @since 1.3.7 + */ + public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) + { + for (; from < to; from++) + if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) + return false; + return true; + } + /** * @param str | String to display! * @param pos | Position to display! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index 871a2c4..bc5e442 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -1,5 +1,8 @@ package org.ugp.serialx.converters; +import static java.lang.Boolean.*; +import static org.ugp.serialx.Utils.equalsLowerCase; + /** * This converter is capable of converting {@link String}. * Its case insensitive! @@ -19,19 +22,19 @@ true - new Boolean(true) + Boolean.TRUE t - new Boolean(true) + Boolean.TRUE false - new Boolean(false) + Boolean.FALSE f - new Boolean(false) + Boolean.FALSE @@ -54,12 +57,16 @@ public BooleanConverter(boolean shorten) } @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - if (arg.equalsIgnoreCase("T") || arg.equalsIgnoreCase("true")) - return new Boolean(true); - if (arg.equalsIgnoreCase("F") || arg.equalsIgnoreCase("false")) - return new Boolean(false); + int len, ch0; + if ((len = str.length()) > 0) + { + if ((ch0 = str.charAt(0) | ' ') == 't' && (len == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4))) + return TRUE; + if (ch0 == 'f' && (len == 1 || len == 5 && equalsLowerCase(str, "false", 1, 5))) + return FALSE; + } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java index 3db9a41..d8c276e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -1,7 +1,5 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.fastReplace; - /** * This converter is capable of converting {@link Character}. * Its case sensitive! @@ -38,16 +36,17 @@ public class CharacterConverter implements DataConverter @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - if (str.length() > 1 && str.charAt(0) == '\'' && str.charAt(str.length()-1) == '\'') + int len; + if ((len = str.length()) > 1 && str.charAt(0) == '\'' && str.charAt(--len) == '\'') try { - if (str.equals("''")) // TODO: str.length() == 2 + mby cache len - return new Character(' '); - return new Character((char) Integer.parseInt(str = fastReplace(str, "'", ""))); + if (len == 1) // str == "''" + return ' '; + return (char) Integer.parseInt(str.substring(1, len)); } catch (Exception e) { - return new Character(str.charAt(0)); + return str.charAt(0); } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index ae3c7af..6cc784e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.converters; +import static org.ugp.serialx.Utils.equalsLowerCase; + /** * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. * Its case insensitive! @@ -19,7 +21,7 @@ null - null (object) + null void @@ -36,10 +38,13 @@ public class NullConverter implements DataConverter @Override public Object parse(ParserRegistry registry, String str, Object... args) { - if (str.equalsIgnoreCase("null")) - return null; - if (str.equalsIgnoreCase("void")) - return VOID; + if (str.length() == 4) + { + if (equalsLowerCase(str, "null", 0, 4)) + return null; + if (equalsLowerCase(str, "void", 0, 4)) + return VOID; + } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 68b0d6c..e45762c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -7,8 +7,6 @@ import java.text.DecimalFormatSymbols; import java.util.Locale; -import org.ugp.serialx.LogProvider; - /** * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! * Its case insensitive! @@ -66,6 +64,8 @@ new Integer(255) new Integer(15) + * + * @see NumberConverter#numberOf(CharSequence, char, int, int) * * @author PETO * @@ -89,47 +89,15 @@ public class NumberConverter implements DataConverter @Override public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { - if (arg.length() > 0) + int len; + if ((len = arg.length()) > 0) { - char ch = arg.charAt(0); - if (ch == '+' || ch == '-' || ch == '.' || (ch >= '0' && ch <= '9')) + char ch0 = arg.charAt(0); + if (ch0 == '+' || ch0 == '-' || ch0 == '.' || (ch0 >= '0' && ch0 <= '9')) { - arg = normFormatNum(arg.toLowerCase()); - ch = arg.charAt(arg.length()-1); //ch = last char - - if (ch == '.') - return CONTINUE; - if (contains(arg, '.') || (!arg.startsWith("0x") && ch == 'f' || ch == 'd')) - { - if (ch == 'f') - return new Float(fastReplace(arg, "f", "")); - return new Double(fastReplace(arg, "d", "")); - } - - try - { - // TODO: Use decode method instead of this mess if possible... - if (ch == 'l') - return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - if (ch == 's') - return new Short(Short.parseShort(fastReplace(fastReplace(fastReplace(arg, "s", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - if (ch == 'y') - return new Byte(Byte.parseByte(fastReplace(fastReplace(arg, "y", ""), "0b", ""), arg.startsWith("0b") ? 2 : 10)); - return new Integer(Integer.parseInt(fastReplace(fastReplace(arg, "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - } - catch (NumberFormatException e) - { - if (arg.matches("[0-9.]+")) - try - { - return new Long(Long.parseLong(fastReplace(fastReplace(fastReplace(arg, "l", ""), "0b", ""), "0x", ""), arg.startsWith("0b") ? 2 : arg.startsWith("0x") ? 16 : 10)); - } - catch (NumberFormatException e2) - { - LogProvider.instance.logErr("Number " + arg + " is too big for its datatype! Try to change its datatype to double (suffix D)!", e2); - return null; - } - } + Number num; + if ((num = numberOf(arg, ch0, --len, 10, 0)) != null) + return num; } } return CONTINUE; @@ -174,6 +142,101 @@ public String format(Number num) return num.toString(); } + /** + * @param str | Source char sequence with number to parse. + * @param ch0 | Should be str.charAt(0). This is to ensure that string is not null or empty and also for possible optimizations. + * @param end | Index of where to end with parsing. If whole string is meant to be parsed, then str.length()-1, should not be greater than that! + * @param base | Base of the parsed number. Theoretically can be anything but usually should be 2, 8, 10 or 16... Note that base will be overridden by suffixes #. for 16, 0x for 16, 0b for 2 or 0 for 8 (only if not followed by .). + * @param type | Preferred datatype of of the number represented by suffixes 'S' for {@link Short}, 'Y' for {@link Byte}, 'L' for {@link Long}, 'D' for {@link Double}, 'F' for {@link Float}. Other stands for {@link Integer}.
+ * Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!
+ * Important thing to know is that this argument will be overridden by suffix from str if present! + * + * @return + * + * @since 1.3.7 + */ + public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) //TODO + { + int start = 0; + + if (ch0 == '#') //Determine base + { + base = 16; + start++; + } + else if (ch0 == '0' && end > 0) + { + int ch1 = str.charAt(1) | ' '; + if (ch1 == 'b') + { + base = 2; + start++; + } + else if (ch1 == 'x') + { + base = 16; + start++; + } + else if (ch1 != '.') + base = 8; + + start++; + } + + double result = 0, baseCof = 1, exponent = 1; + int chEnd = str.charAt(end--) | ' '; //Determine data type + if (base == 10 ? chEnd >= 'd' : chEnd >= 'l') + type = chEnd; + else if (chEnd == '.') + type = 'd'; + else + { + result = chEnd > '9' ? chEnd - 'a' + 10 : chEnd - '0'; + baseCof = base; + } + + for (int ch; end >= start; end--) //Parsing + { + if ((ch = str.charAt(end)) == '-') // Neg + result = -result; + else if (ch == '.') //Decimal + { + result /= baseCof; + baseCof = 1; + if (type == 0) + type = 'd'; + } + else if ((ch |= ' ') == 'e' && base == 10) //Handle E-notation + { + if ((exponent = Math.pow(base, result)) < 1 && type == 0) + type = 'd'; + result = 0; + baseCof = 1; + } + else if (ch == ' ') //Not valid + return null; + else if (ch != 127 && ch != '+') + { + result += (ch > '9' ? ch - 'a' + 10 : ch - '0') * baseCof; + baseCof *= base; + } + } + + result *= exponent; + + if (type == 'd') + return result; + if (type == 'f') + return (float) result; + if (type == 'l' || result > 0x7fffffff || result < 0x80000000) + return (long) result; + if (type == 's') + return (short) result; + if (type == 'y') + return (byte) result; + return (int) result; + } + /** * @param num | Number string to format! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 33984bb..d7ae1d7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -43,6 +43,17 @@ public class StringConverter implements DataConverter */ public static boolean serializeStringNormally = true; + @Override + public String parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len; + if ((len = str.length()) > 1 && str.charAt(0) == '\"' && str.charAt(--len) == '\"' && indexOfNotInObj(str, ' ') == -1) + { + return str.substring(1, len); + } + return CONTINUE; + } + @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) { @@ -67,14 +78,6 @@ else if (serializeStringNormally) return CONTINUE; } - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (str.length() > 1 && str.charAt(0) == '\"' && str.charAt(str.length()-1) == '\"' && indexOfNotInObj(str, ' ') == -1) - return str.substring(1, str.length() - 1); - return CONTINUE; - } - @Override public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) { From 0552ca3095232e3e98333d2ed9a03bbc958a9cbd Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Thu, 11 Apr 2024 10:40:31 +0200 Subject: [PATCH 22/75] NumConv docs --- .../serialx/converters/NumberConverter.java | 25 +++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index e45762c..f49eafe 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -63,9 +63,29 @@ new Integer(255) 0b1111 new Integer(15) + + 0112 + new Integer(74) + + + 0112 + new Integer(74) + + + 10e2 + new Integer(10e2) + + + 10e2 + new Integer(10e2) + + + .1e2 + new Double(0.1e2) + * - * @see NumberConverter#numberOf(CharSequence, char, int, int) + * @see NumberConverter#numberOf(CharSequence, char, int, int, int) * * @author PETO * @@ -151,7 +171,8 @@ public String format(Number num) * Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!
* Important thing to know is that this argument will be overridden by suffix from str if present! * - * @return + * @return {@link Number} parsed from str with rules specified above. This function was designed to act as more optimized merger of {@link Byte#valueOf(String, int)}, {@link Short#valueOf(String, int)}, {@link Integer#valueOf(String, int)}, {@link Long#valueOf(String, int)} and {@link Float#valueOf(String)}, {@link Double#valueOf(String)} all encapsulated in 1 universal function.
+ * Note: This function will not check for incorrect number formats in order to save performance. Only incorrect format is when inserted string contains space, in this case it will return null! * * @since 1.3.7 */ From ea69c1ac86e27159fb278eaeaaf077088d6a0c28 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 16 Apr 2024 16:42:35 +0200 Subject: [PATCH 23/75] add ability to cache for StringConv --- .../serialx/converters/NumberConverter.java | 2 +- .../serialx/converters/StringConverter.java | 39 ++++++++++++++++++- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index f49eafe..df92bd9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -176,7 +176,7 @@ public String format(Number num) * * @since 1.3.7 */ - public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) //TODO + public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) { int start = 0; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index d7ae1d7..5b2c35c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -3,6 +3,8 @@ import static org.ugp.serialx.Utils.contains; import static org.ugp.serialx.Utils.indexOfNotInObj; +import java.util.Map; + import org.ugp.serialx.Registry; /** @@ -41,14 +43,24 @@ public class StringConverter implements DataConverter * * @since 1.2.0 (moved to {@link StringConverter} since 1.3.0) */ - public static boolean serializeStringNormally = true; + public static boolean serializeStringNormally = true; //TODO + + protected Map parsingCache; @Override public String parse(ParserRegistry myHomeRegistry, String str, Object... args) { + String result; int len; if ((len = str.length()) > 1 && str.charAt(0) == '\"' && str.charAt(--len) == '\"' && indexOfNotInObj(str, ' ') == -1) { + if (parsingCache != null) + { + if ((result = parsingCache.get(str)) != null) + return result; + parsingCache.put(str, result = str.substring(1, len)); + return result; + } return str.substring(1, len); } return CONTINUE; @@ -90,6 +102,31 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob return ""; } + /** + * @param cache | Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool. Doing this can save you some memory with minimal performance overhead!
+ * Setting this to null will disable the parsing result caching by this {@link StringConverter} as it is by default.
+ * Recommended: Enable this when parsing a lot of strings that are the same, otherwise this will not have a big impact.
+ * Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! + * + * @since 1.3.7 + */ + public void setParsingCache(Map cache) + { + parsingCache = cache; + } + + /** + * @return Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool.
+ * Null will be returned if caching is disabled, which is by default...
+ * Note: Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! + * + * @since 1.3.7 + */ + public Map getParsingCache() + { + return parsingCache; + } + /** * @param obj | Object to stringify directly. * From ef49dcdbd1a8a6670d359f693d9688290be4fa30 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 26 Apr 2024 15:11:32 +0200 Subject: [PATCH 24/75] moving some juss specifc prots to juss module and fixing some small mistakes --- .../main/java/org/ugp/serialx/juss}/protocols/AutoProtocol.java | 0 .../java/org/ugp/serialx/juss}/protocols/SelfSerializable.java | 0 .../org/ugp/serialx/juss}/protocols/SelfSerializableProtocol.java | 0 .../juss}/protocols/UniversalObjectInstantiationProtocol.java | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/protocols/AutoProtocol.java (100%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/protocols/SelfSerializable.java (100%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/protocols/SelfSerializableProtocol.java (100%) rename {SerialX-core/src/main/java/org/ugp/serialx => SerialX-juss/src/main/java/org/ugp/serialx/juss}/protocols/UniversalObjectInstantiationProtocol.java (100%) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/protocols/AutoProtocol.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializable.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/protocols/SelfSerializableProtocol.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java similarity index 100% rename from SerialX-core/src/main/java/org/ugp/serialx/protocols/UniversalObjectInstantiationProtocol.java rename to SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java From 69af2e6ace0000e738ab8442135d225119ff4086 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 26 Apr 2024 15:12:24 +0200 Subject: [PATCH 25/75] ... --- .../src/main/java/org/ugp/serialx/Serializer.java | 2 +- .../org/ugp/serialx/converters/DataParser.java | 2 +- .../org/ugp/serialx/protocols/EnumProtocol.java | 4 +--- .../serialx/protocols/SerializationProtocol.java | 2 +- .../ugp/serialx/juss/protocols/AutoProtocol.java | 8 +++++--- .../serialx/juss/protocols/SelfSerializable.java | 6 ++---- .../juss/protocols/SelfSerializableProtocol.java | 15 +++++++++++---- .../UniversalObjectInstantiationProtocol.java | 8 +++++--- 8 files changed, 27 insertions(+), 20 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index f677009..5ceb1dc 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -36,7 +36,7 @@ /** * {@link org.ugp.serialx.Serializer} is powerful utility class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s. - * This class itself is responsible for utility, formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage! + * This class itself is responsible for formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage! * It is instance of {@link Scope} so we can say that this is scope that can serialize itself using system of already mentioned {@link DataParser} and {@link SerializationProtocol}! * * @author PETO diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 7498674..436cc19 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -7,7 +7,7 @@ import org.ugp.serialx.Scope; /** - * This class supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! + * This interface is supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! * Instance of DataParser should be registered into {@link DataParser#REGISTRY} or other external registry in order to work, also only one instance of each DataParser should be used and accessed via this registry!
* Static method {@link DataParser#parseObj} is used to walk this registry and parse inserted string in process, in other words we can say that this interface contains recursive descent parse that uses its own implementations! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java index f0bba4d..1bf6709 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java @@ -1,9 +1,7 @@ package org.ugp.serialx.protocols; -import java.util.Collection; - /** - * EnumProtocol is universal protocol to serialize any enumerator ({@link Collection} instance). + * EnumProtocol is universal protocol to serialize any enumerator ({@link Enum} instance). * * @author PETO * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 13248f3..2b8d50a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -30,7 +30,7 @@ public abstract class SerializationProtocol * * @since 1.3.0 */ - public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new SelfSerializableProtocol(), new EnumProtocol()); + public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class), new SelfSerializableProtocol(SelfSerializable.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new EnumProtocol()); /** * This mode is for protocols that are used for serialization only! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index cb717f7..fc0fd00 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -1,4 +1,6 @@ -package org.ugp.serialx.protocols; +package org.ugp.serialx.juss.protocols; + +import static org.ugp.serialx.Utils.Instantiate; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -8,7 +10,7 @@ import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.Utils; +import org.ugp.serialx.protocols.SerializationProtocol; /** * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! @@ -128,7 +130,7 @@ public AutoProtocol(Class applicableFor, boolean useScope, List objectClass) throws Exception { - return Utils.Instantiate(objectClass); + return Instantiate(objectClass); } @Override diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java index 3c35d90..1619025 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java @@ -1,9 +1,7 @@ -package org.ugp.serialx.protocols; - -import java.io.Serializable; +package org.ugp.serialx.juss.protocols; /** - * This is based on pretty similar concept as regular {@link Serializable} is! However this interface is meant to create its instance programmatically via constructor! + * This is based on pretty similar concept as regular {@link java.io.Serializable} is! However this interface is meant to create its instance programmatically via constructor! * So condition of using this is that array of objects returned by {@link SelfSerializable#serialize()} must be applicable for some public constructor of certain class implementing this! * Specific instances of this interface will be created by calling that public constructor! This is done reflectively by {@link SelfSerializableProtocol}! * diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index d4eac0d..efa1aaa 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -1,4 +1,4 @@ -package org.ugp.serialx.protocols; +package org.ugp.serialx.juss.protocols; /** * SelfSerializableProtocol is universal protocol to serialize any {@link SelfSerializable} instance. The condition of use is implementation of {@link SelfSerializable} interface and public constructor that can be called with content returned by specific {@link SelfSerializable#serialize()}! @@ -11,13 +11,19 @@ */ public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol { - public SelfSerializableProtocol() + /** + * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
+ * Note: Passing {@link SelfSerializable#getClass()} will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered unsafe in some cases... + * + * @since 1.3.7 + */ + public SelfSerializableProtocol(Class applicableFor) { - super(SelfSerializable.class); + super(applicableFor); } @Override - public Object[] serialize(SelfSerializable object) + public Object[] serialize(SelfSerializable object) { return object.serialize(); } @@ -28,3 +34,4 @@ public byte getMode() return MODE_ALL; } } + \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index 045401e..a773ea9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -1,10 +1,11 @@ -package org.ugp.serialx.protocols; +package org.ugp.serialx.juss.protocols; import java.lang.reflect.Constructor; import java.util.Arrays; import org.ugp.serialx.LogProvider; import org.ugp.serialx.Utils; +import org.ugp.serialx.protocols.SerializationProtocol; /** * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! @@ -18,14 +19,15 @@ */ public class UniversalObjectInstantiationProtocol extends SerializationProtocol { - protected final Class applicableFor; + protected final Class applicableFor; /** * @param applicableFor | Class that can be serialized using this protocol. + * Note: Passing {@link Object#getClass()} will make this protocol universal and work for any {@link Object} instance, this can be considered unsafe in some cases... * * @since 1.3.7 */ - public UniversalObjectInstantiationProtocol(Class applicableFor) + public UniversalObjectInstantiationProtocol(Class applicableFor) { this.applicableFor = applicableFor; } From fc2b9d1fda39b8c080af4e8cd77a2465338fdb1e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 30 Apr 2024 14:35:54 +0200 Subject: [PATCH 26/75] removing deprecateds --- .../main/java/org/ugp/serialx/Serializer.java | 275 ------------------ .../ugp/serialx/converters/DataConverter.java | 37 --- .../ugp/serialx/converters/DataParser.java | 76 ----- .../SerializableBase64Converter.java | 14 - .../serialx/juss/protocols/AutoProtocol.java | 26 +- .../operators/ArithmeticOperators.java | 13 - 6 files changed, 2 insertions(+), 439 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 5ceb1dc..1b3c9a0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -578,281 +578,6 @@ public A SerializeAsSubscope(A source, char[] wrappingBra source = (A) SerializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)); return (A) source.append(wrappingBrackets[1]); } - - /* - * @param file | File with specific format content. - * @param index | Index of value to get from lowest Scope. - * - * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(file).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! - * But target value can't be using any variables declared outside and also can't be variable invocation itself! Also there might be some problems with commented code! Also there can't be no variables in file! - * - * @since 1.2.5 - * - @Deprecated - public T LoadFrom(File file, int index) - { - try - { - return LoadFrom(new FileReader(file), index); - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - return null; - } - - /** - * @param str | Any {@link CharSequence} with specific format content. - * @param index | Index of value to get from lowest Scope. - * - * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(str).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! - * But target value can't be using any variables declared outside and also can't be variable invocation itself! Also there might be some problems with commented code! - * - * @since 1.2.5 - * - @Deprecated - public T LoadFrom(CharSequence str, int index) - { - return LoadFrom(new StringReader(str.toString()), index); - } - - /** - * @param reader | Any {@link Reader} with specific format content. - * @param index | Index of value to get from lowest Scope. - * - * @return Value with index in lowest Scope. Similar to Serializer.LoadFrom(reader).get(index) however this function is specifically designed to load only that 1 value witch saves alto of performance! - * But target value can't be using any variables declared outside and also can't be variable invocation itself! - * - * @since 1.2.5 - * - @Deprecated - @SuppressWarnings("unchecked") - public T LoadFrom(Reader reader, int index) - { - StringBuilder sb = new StringBuilder(); - int semicolon = 0, brackets = 0, quote = 0, vars = 0, multLineCom = -1; - - String line; - try - { - BufferedReader lineReader = new BufferedReader(reader); - while ((line = lineReader.readLine()) != null) - { - if (!contains(line = line.trim(), '=', ':') || !(brackets == 0 && quote % 2 == 0)) - for (int i = 0, com = -1, len = line.length(); i < len; i++) - { - char ch = line.charAt(i); - - if (ch == '/' && i < len-1 && line.charAt(i+1) == '/') - com++; - else if (multLineCom <= -1 && ch == '"') - quote++; - - boolean notInObj = brackets == 0 && quote % 2 == 0; - if (semicolon > index) - { - lineReader.close(); - return (T) DataParser.parseObj(DataParser.REGISTRY, sb.toString(), this); - } - - if (multLineCom > -1 || com > -1) //Is comment - { - if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') - multLineCom = -1; - } - else if (ch == '/' && i < len-1) - { - char chNext = line.charAt(i+1); - if (chNext == '*') - i += multLineCom = 1; - else - sb.append(ch); - } - /*else if (notInObj && ch == '=') - { - vars++; - }* - else if (notInObj && isOneOf(ch, ';', ',')) - { - if (vars > 0) - { - vars = 0; - } - else - semicolon++; - } - else - { - if (ch | ' ') == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - { - lineReader.close(); - throw new IllegalArgumentException("Missing closing bracket in: " + line); - } - } - - if (vars == 0 && semicolon == index) - sb.append(ch); - } - } - else - { - char lastCh = line.charAt(line.length()-1); - if (isOneOf(lastCh, '{', '[')) - brackets++; - if (isOneOf(lastCh, ';', ',')) - vars++; - } - - } - } - catch (IOException e) - { - e.printStackTrace(); - } - - if (brackets > 0) - throw new IllegalArgumentException("Unclosed brackets!"); - else if (quote % 2 != 0) - throw new IllegalArgumentException("Unclosed or missing quotes!"); - else if (!(line = sb.toString()).isEmpty()) - return (T) DataParser.parseObj(DataParser.REGISTRY, line, this); - LogProvider.instance.logErr("Value with index " + index + " is out of bounds!"); - return null; - } - - /** - * @param file | File with specific format content. - * @param varName | Name of variable to load! - * - * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(file).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! - * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! - * - * @since 1.2.5 - * - @Deprecated - public T LoadFrom(File file, String varName) - { - try - { - return LoadFrom(new FileReader(file), varName); - } - catch (FileNotFoundException e) - { - e.printStackTrace(); - } - return null; - } - - /** - * @param str | Any {@link CharSequence} with specific format content. - * @param varName | Name of variable to load! - * - * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(str).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! - * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! - * - * @since 1.2.5 - * - @Deprecated - public T LoadFrom(CharSequence str, String varName) - { - return LoadFrom(new StringReader(str.toString()), varName); - } - - /** - * @param reader | Any {@link Reader} with specific format content. - * @param varName | Name of variable to load! - * - * @return Value of variable with varName in lowest Scope. Similar to Serializer.LoadFrom(reader).get(varName) however this function is specifically designed to load only that 1 variable witch saves alto of performance! - * But target variable can't be using any variables declared outside! Also there might be some problems with commented code! - * - * @since 1.2.5 - * - @Deprecated - @SuppressWarnings("unchecked") - public T LoadFrom(Reader reader, String varName) - { - StringBuilder sb = new StringBuilder(); - int brackets = 0, quote = 0, multLineCom = -1, fromIndex = 0, fromIndexOrig = 0, findIndex = -1; - - String line; - try - { - BufferedReader lineReader = new BufferedReader(reader); - while ((line = lineReader.readLine()) != null) - { - if (findIndex <= -1 && multLineCom <= -1 && line.length() > varName.length() && !(line.charAt(0) == '/' && isOneOf(line.charAt(1), '/', '*')) && (findIndex = line.indexOf(varName)) > -1) - { - fromIndexOrig = fromIndex = findIndex; - findIndex+=sb.length(); - } - - for (int com = -1, len = line.length(); fromIndex < len; fromIndex++) - { - char ch = line.charAt(fromIndex); - - if (ch == '/' && fromIndex < len-1 && line.charAt(fromIndex+1) == '/') - com++; - else if (multLineCom <= -1 && ch == '"') - quote++; - - if (findIndex > -1 && quote % 2 == 0 && brackets == 0 && isOneOf(ch, ';', ',')) - { - lineReader.close(); - int start = sb.indexOf("=", findIndex-fromIndexOrig); - if (start <= -1) - start = sb.indexOf(":", findIndex-fromIndexOrig); - return (T) DataParser.parseObj(DataParser.REGISTRY, sb.substring(start+1), this); - } - - if (multLineCom > -1 || com > -1) //Is comment - { - if (multLineCom > 0 && ch == '*' && fromIndex < len-1 && line.charAt(++fromIndex) == '/') - multLineCom = -1; - } - else if (ch == '/' && fromIndex < len-1) - { - char chNext = line.charAt(fromIndex+1); - if (chNext == '*') - fromIndex = multLineCom = 1; - else - sb.append(ch); - } - else - { - if (ch | ' ') == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - { - lineReader.close(); - throw new IllegalArgumentException("Missing closing bracket in: " + line); - } - } - - sb.append(ch); - } - } - fromIndex = 0; - } - } - catch (IOException e) - { - e.printStackTrace(); - } - - LogProvider.instance.logErr("Variable " + varName + " was not found!"); - return null; - }*/ /** * @param indexWithStringValue | Index of independent value that should be string. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index c6fadf4..2c157f5 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -54,43 +54,6 @@ public static CharSequence objToString(Object obj, Object... args) return REGISTRY.toString(obj, args); } - /** - * @deprecated Use {@link ParserRegistry#toString(Object, Object...)}! - * - * @param registry | Registry to use! - * @param obj | Object to convert into string! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return Object converted to string using {@link DataConverter} suitable converter picked from registry! - * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! - * - * @since 1.3.0 - */ - @Deprecated - public static CharSequence objToString(Registry registry, Object obj, Object... args) - { - if (registry instanceof ParserRegistry) - return ((ParserRegistry) registry).toString(obj, args); - return objToString(new ParserRegistry(registry), obj, args); - } - - /** - * @deprecated Use {@link ParserRegistry#getConverterFor(Object, Object...)}! - * - * @param registry | Registry to use! - * @param obj | Object to find converter for! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return Converter suitable for converting required obj to string, selected from registry! - */ - @Deprecated - public static DataConverter getConverterFor(Registry registry, Object obj, Object... args) - { - if (registry instanceof ParserRegistry) - return ((ParserRegistry) registry).getConverterFor(obj, args); - return getConverterFor(new ParserRegistry(registry), obj, args); - } - /** * @return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataParser.class.getName() * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 436cc19..828e550 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -68,82 +68,6 @@ public static Object parseObj(String str, Object... args) return REGISTRY.parse(str, args); } - /** - * @deprecated Use {@link ParserRegistry#parse(String, Object...)}! - * - * @param registry | Registry to use! - * @param str | Source string to parse using suitable parser from registry. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. - * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! - * - * @since 1.3.0 - */ - @Deprecated - public static Object parseObj(Registry registry, String str, Object... args) - { - return parseObj(registry, str, false, null, args); - } - - /** - * @deprecated Use {@link ParserRegistry#parse(String, boolean, Class[], Object...)}! - * - * @param registry | Registry to use! - * @param str | Source string to parse using suitable parser from registry. - * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message! - * @param ignore | {@link DataParser} class to ignore! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. - * If no suitable result was found, null or inserted string will be returned based on returnAsStringIfNotFound! - * - * @since 1.3.0 - */ - @Deprecated - public static Object parseObj(Registry registry, String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) - { - if (registry instanceof ParserRegistry) - return ((ParserRegistry) registry).parse(str, returnAsStringIfNotFound, ignore, args); - return parseObj(new ParserRegistry(registry), str, returnAsStringIfNotFound, ignore, args); - } - - /** - * @deprecated Use {@link DataParser.REGISTRY#getParserFor(String, Object...)}! - * - * @param registry | Registry to search! - * @param str | String to find parser for! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Parser suitable for parsing required string, selected from {@link DataParser#REGISTRY}! - * - * @since 1.3.0 - */ - @Deprecated - public static DataParser getParserFor(String str, Object... args) - { - return getParserFor(REGISTRY, str, args); - } - - /** - * @deprecated Use {@link DataParser#getParserFor(String, Object...)}! - * - * @param registry | Registry to search! - * @param str | String to find parser for! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Parser suitable for parsing required string, selected from inserted registry! - * - * @since 1.3.0 - */ - @Deprecated - public static DataParser getParserFor(Registry registry, String str, Object... args) - { - if (registry instanceof ParserRegistry) - return ((ParserRegistry) registry).getParserFor(str, args); - return getParserFor(new ParserRegistry(registry), str, args); - } - /** * Registry to store {@link DataParser} and {@link DataConverter} and performing parsing (String -> Object) and converting (Object -> String) operations with them! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index b2bb26a..4d8dce4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -48,20 +48,6 @@ new ArrayList() */ public class SerializableBase64Converter implements DataConverter { - /** - * @deprecated DO NOT USE, IT WILL TAKE NOTE EFFECT! USE {@link ObjectConverter#setUseBase64IfCan(boolean)}! - * - * Set this on true to force program to use SerializationProtocol also on java.io.Serializable objects. - * Doing this also might take less memory space then using classic java.io.Serializable. - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization! - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) - */ - @Deprecated - public static boolean useProtocolIfCan = true; - @Override public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index fc0fd00..1f869ed 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -173,15 +173,13 @@ public T unserialize(Class objectClass, Object... args) throws Exce } /** - * @deprecated DO NOT USE! - * * @param variableName | Name of variable! * - * @return PropertyDescriptor of variable with name or null if this protocols can't use it! + * @return PropertyDescriptor of variable with name or null if this protocols can't serialize variable with given name!
+ * Note: I would recommend to tread this as read only and not set anything that you are not sure of. This will ensure correct functionality... * * @since 1.3.2 */ - @Deprecated public PropertyDescriptor getfieldDescriptorsDescriptor(String variableName) { for (PropertyDescriptor var : fieldDescriptors) @@ -215,24 +213,4 @@ public void setUseScope(boolean useScope) { this.useScope = useScope; } - - /** - * DEPRECATED: DO NOT USE! USE {@link Scope#getPropertyDescriptorsOf(Class, String...)} instead! - * - * @param cls | Class to inspect! - * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! - * - * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! - * - * @throws IntrospectionException when there are no fields with valid and public getters and setters. - * - * @see PropertyDescriptor - * - * @since 1.3.2 - */ - @Deprecated - public static List getPropertyDescriptorsOf(Class cls, String... fieldNames) throws IntrospectionException - { - return Scope.getPropertyDescriptorsOf(cls, fieldNames); - } } diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index c05f137..c55cbf1 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -456,19 +456,6 @@ else if (obj instanceof Character) return obj; } - /** - * DEPRECATED: Use {@link String#valueOf(Object)} instead, this function is duplicate functionality rendering it unnecessary. - * - * @return "null" if null and else obj.toString(); - * - * @since 1.3.0 - */ - @Deprecated - public static String toString(Object obj) - { - return obj == null ? "null" : obj.toString(); - } - /** * Used internally by {@link ArithmeticOperators} to wrap result of evaluation! * Mainly used by String results! From 211bae29432cc9dea86e5ad34ce119f014a7418f Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 11 May 2024 23:35:50 +0200 Subject: [PATCH 27/75] testing, fixing, jdocking, finilizing --- .../main/java/org/ugp/serialx/Serializer.java | 2 +- .../src/main/java/org/ugp/serialx/Utils.java | 78 +++++++++---------- .../serialx/converters/NumberConverter.java | 3 + .../serialx/converters/StringConverter.java | 22 +++++- .../ugp/serialx/protocols/ListProtocol.java | 4 +- .../converters/JsonCharacterConverter.java | 39 ++++++++-- .../json/converters/JsonNumberConverter.java | 11 ++- .../juss/converters/OperationGroups.java | 2 +- .../juss/converters/VariableConverter.java | 48 +++++++----- .../operators/ArithmeticOperators.java | 2 +- 10 files changed, 136 insertions(+), 75 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 1b3c9a0..3dcd9e9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -534,7 +534,7 @@ public Object apply(Object t) if (t instanceof Serializer) { GenericScope srl = ((Scope) t).transform(this); - return new GenericScope<>(srl.variables(), srl.values(), srl.getParent()); + return new Scope(srl.variables(), srl.values(), srl.getParent()); } return t; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 75326ee..ef21e16 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -223,14 +223,14 @@ public static T Clone(T obj) /** * @param obj | Object to clone. - * @param + * @param parsersToUse | Parsers that will be used for cloning... * @param converterArgs | Argument for {@link DataConverter#objToString(Registry, Object, Object...)}! * @param parserArgs | Arguments for {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)}! * * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
* Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! Also note that certain objects such as primitive wrappers ({@link Integer}, {@link Float} etc...) will not be necessarily cloned since cloning them is not reasonable... * * @since 1.3.2 */ @@ -238,49 +238,47 @@ public static T Clone(T obj) public static T Clone(T obj, Registry parsersToUse, Object[] converterArgs, Object... parserArgs) { if (obj == null) - return obj; - else if (obj.getClass() == Byte.class) - return (T) new Byte((byte) obj); - else if (obj.getClass() == Short.class) - return (T) new Short((short) obj); - else if (obj.getClass() == Integer.class) - return (T) new Integer((int) obj); - else if (obj.getClass() == Long.class) - return (T) new Long((long) obj); - else if (obj.getClass() == Float.class) - return (T) new Float((float) obj); - else if (obj.getClass() == Double.class) - return (T) new Double((double) obj); - else if (obj.getClass() == Character.class) - return (T) new Character((char) obj); - else if (obj.getClass() == Boolean.class) - return (T) new Boolean((boolean) obj); - else if (obj.getClass() == String.class) + return null; + if (obj.getClass() == Byte.class) + return (T) (Byte) ((byte) obj); // valueOf call... + if (obj.getClass() == Short.class) + return (T) (Short) ((short) obj); + if (obj.getClass() == Integer.class) + return (T) (Integer) ((int) obj); + if (obj.getClass() == Long.class) + return (T) (Long) ((long) obj); + if (obj.getClass() == Float.class) + return (T) (Float) ((float) obj); + if (obj.getClass() == Double.class) + return (T) (Double) ((double) obj); + if (obj.getClass() == Character.class) + return (T) (Character) ((char) obj); + if (obj.getClass() == Boolean.class) + return (T) (Boolean) ((boolean) obj); + if (obj.getClass() == String.class) return (T) new String((String) obj); - else + + ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); + + Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); + if (cln != null && cln != VOID) + return (T) cln; + + if (obj instanceof Cloneable) { - ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); - - Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); - if (cln != null && cln != VOID) - return (T) cln; - - if (obj instanceof Cloneable) + try { - try - { - Method method = Object.class.getDeclaredMethod("clone"); - method.setAccessible(true); - return (T) method.invoke(obj); - } - catch (Exception e) - { - throw new RuntimeException(e); - } + Method method = Object.class.getDeclaredMethod("clone"); + method.setAccessible(true); + return (T) method.invoke(obj); + } + catch (Exception e) + { + throw new RuntimeException(e); } - LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); - return obj; } + LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); + return obj; } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index df92bd9..4f3fa34 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -259,12 +259,15 @@ else if (ch != 127 && ch != '+') } /** + * @deprecated THIS IS NO LONGER NECESSARY BECAUSE BECAUSE {@link NumberConverter#numberOf(CharSequence, char, int, int, int)} CAN DO THE SAME THING MUCH FASTET! + * * @param num | Number string to format! * * @return Original string with formated sign and deleted '_'! * * @since 1.3.0 */ + @Deprecated public static String normFormatNum(String num) { if (num.length() > 2) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 5b2c35c..1314103 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -43,7 +43,7 @@ public class StringConverter implements DataConverter * * @since 1.2.0 (moved to {@link StringConverter} since 1.3.0) */ - public static boolean serializeStringNormally = true; //TODO + protected boolean serializeStringNormally = true; protected Map parsingCache; @@ -127,6 +127,26 @@ public Map getParsingCache() return parsingCache; } + /** + * @return Will return value of {@link StringConverter#serializeStringNormally}! + * + * @since 1.3.7 (it was static before = not good) + */ + public boolean isSerializeStringNormally() + { + return serializeStringNormally; + } + + /** + * @param serializeStringNormally | Set value of {@link StringConverter#serializeStringNormally}! + * + * @since 1.3.7 (it was static before = not good) + */ + public void setSerializeStringNormally(boolean serializeStringNormally) + { + this.serializeStringNormally = serializeStringNormally; + } + /** * @param obj | Object to stringify directly. * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java index d2d99a8..f300466 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java @@ -11,7 +11,7 @@ * * @since 1.0.0 and applicable for {@link Collection} since 1.2.2 */ -public class ListProtocol extends SerializationProtocol> +public class ListProtocol extends SerializationProtocol> { @Override public Object[] serialize(Collection obj) @@ -24,7 +24,7 @@ public Collection unserialize(Class> objectClass, Obj { if (objectClass.isInterface()) return new ArrayList<>(Arrays.asList(args)); - + try { return objectClass.getConstructor(Collection.class).newInstance(Arrays.asList(args)); diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java index 0850e25..d9fc561 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java @@ -2,27 +2,52 @@ import org.ugp.serialx.converters.CharacterConverter; -public class JsonCharacterConverter extends CharacterConverter { - +/** + * {@link CharacterConverter} modified to match JSON more closely. It will serialize char as {@link String} since JSON does not know char... + * + * @author PETO + * + * @since 1.3.7 + */ +public class JsonCharacterConverter extends CharacterConverter +{ protected boolean formatAsString; - public JsonCharacterConverter(boolean formatAsString) { - setFormatAsString(formatAsString); + /** + * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). + * + * @since 1.3.7 + */ + public JsonCharacterConverter(boolean formatAsString) + { + setFormatAsString(formatAsString); } @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { if (obj instanceof Character) - return isFormatAsString() ? obj.toString() : String.valueOf((int) (char) obj); + return isFormatAsString() ? "\""+obj+"\"" : String.valueOf((int) (char) obj); return CONTINUE; } - public boolean isFormatAsString() { + /** + * @return True if character is going to be serialized in a letter form. If false, it will be serialized as ASCII value (int). + * + * @since 1.3.7 + */ + public boolean isFormatAsString() + { return formatAsString; } - public void setFormatAsString(boolean formatAsString) { + /** + * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). + * + * @since 1.3.7 + */ + public void setFormatAsString(boolean formatAsString) + { this.formatAsString = formatAsString; } } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java index 1aaec5b..0f2e76e 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -2,8 +2,15 @@ import org.ugp.serialx.converters.NumberConverter; -public class JsonNumberConverter extends NumberConverter { - +/** + * {@link NumberConverter} modified to match JSON more closely. It will not use Juss number suffixes since JSON does not support them... + * + * @author PETO + * + * @since 1.3.7 + */ +public class JsonNumberConverter extends NumberConverter +{ @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 005603d..9315151 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -52,7 +52,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) args[2] = runtimeGroupStack; } String mark = GROUP_MARK_OP + runtimeGroupStack.size() + GROUP_MARK_CLS; - runtimeGroupStack.put(mark, str.substring(opIndex+1, clsIndex)); + runtimeGroupStack.put(mark, str.substring(opIndex+1, clsIndex).trim()); StringBuilder sb = new StringBuilder(str).replace(opIndex, clsIndex+1, mark); return myHomeRegistry.parse(sb.toString(), args); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index c3f57f5..a18a471 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -81,32 +81,40 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... Yea this is not the prettiest code but it does the job and mainly it does it fast so shut up! { String var = vars[i]; - if (!genericVar && contains(var, ' ')) - LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); - else if ((op0Index = var.indexOf('.')) > -1) + if (!genericVar) { - String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); - int iLast = path.length-1, j = 0; - - backlook: do + if (contains(var, ' ')) { - Object sc; - if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... + LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); + continue; + } + + if ((op0Index = var.indexOf('.')) > -1) + { + String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); + int iLast = path.length-1, j = 0; + + backlook: do { - for (j = 1; j < iLast; j++) // Subscope/forward lookup (inner path only)... - if ((sc = getMemberOperator(sc, path[j])) == null || sc == VOID) - break backlook; - - setMemberOperator(myHomeRegistry, sc, path[iLast], val, genericVar, args); - continue eachVar; + Object sc; + if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... + { + for (j = 1; j < iLast; j++) // Subscope/forward lookup (inner path only)... + if ((sc = getMemberOperator(sc, path[j])) == null || sc == VOID) + break backlook; + + setMemberOperator(myHomeRegistry, sc, path[iLast], val, false, args); + continue eachVar; + } } + while ((scope = scope.getParent()) != null); + + LogProvider.instance.logErr("Path \"" + var + "\" cannot be set to \"" + val + "\" because \"" + path[j] + "\" is not a accessible or does not exist!", null); + continue; } - while ((scope = scope.getParent()) != null); - - LogProvider.instance.logErr("Path \"" + var + "\" cannot be set to \"" + val + "\" because \"" + path[j] + "\" is not a accessible or does not exist!", null); } - else - setMemberOperator(myHomeRegistry, scope, var, val, genericVar, args); + + setMemberOperator(myHomeRegistry, scope, var, val, genericVar, args); } return getValueModif ? val : VOID; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index c55cbf1..0837750 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -335,7 +335,7 @@ else if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Flo else if (cof instanceof Integer || cof2 instanceof Integer) return (int) pow; } - return null; + return null; } /** From 39fdb1f202eb143fe68a71767fb7e79b17cd6dcd Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 28 Jun 2024 23:16:12 +0200 Subject: [PATCH 28/75] Adding/improving some docs, fixing some bugs (CharConv...), Improving SerializationDebuger (OUT, it shows exceptions...), Improving LogProvider, Refactoring/improivng operators, Logical, Comparasional, adding numeric and logical negation... ConditionalAsigment. Improving some other things... --- .../java/org/ugp/serialx/LogProvider.java | 4 +- .../src/main/java/org/ugp/serialx/Utils.java | 29 ++-- .../serialx/converters/BooleanConverter.java | 17 ++- .../converters/CharacterConverter.java | 2 +- .../ugp/serialx/converters/DataConverter.java | 2 +- .../ugp/serialx/converters/DataParser.java | 8 +- .../serialx/converters/NumberConverter.java | 2 +- .../{converters => }/DebugParserRegistry.java | 47 ++++--- .../devtools/SerializationDebugger.java | 109 +++++++++------ .../org/ugp/serialx/json/JsonSerializer.java | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 2 +- .../operators/ArithmeticOperators.java | 46 ++++--- .../operators/ComparisonOperators.java | 53 ++++---- .../ConditionalAssignmentOperators.java | 35 +++-- .../operators/LogicalOperators.java | 127 +++++++----------- .../operators/NegationOperator.java | 24 +++- 16 files changed, 279 insertions(+), 230 deletions(-) rename SerialX-devtools/src/main/java/org/ugp/serialx/devtools/{converters => }/DebugParserRegistry.java (79%) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java index f9eadae..b68d533 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java @@ -36,8 +36,8 @@ public void logErr(Object obj, Throwable ex) { if (reThrowException) { - if (ex == null) - throw new RuntimeException(obj.toString()); + if (ex == null || ex.getMessage() == null || ex.getMessage().isEmpty()) + throw new RuntimeException(String.valueOf(obj)); throw new RuntimeException(ex); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index ef21e16..43dd25c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -590,30 +590,32 @@ else if (quote % 2 != 0) * @param s | CharSequence to search! * @param oneOf | Characters to find! * - * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! * * @since 1.3.0 */ public static int indexOfNotInObj(CharSequence s, char... oneOf) { - return indexOfNotInObj(s, true, oneOf); + return indexOfNotInObj(s, 0, s.length(), true, oneOf); } /** * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be s.length()). * @param firstIndex | If true, first index will be returned, if false last index will be returned. * @param oneOf | Characters to find! * - * @return Index of first found character that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! * * @since 1.3.5 */ - public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... oneOf) + public static int indexOfNotInObj(CharSequence s, int from, int to, boolean firstIndex, char... oneOf) { - int found = -1; - for (int i = 0, brackets = 0, quote = 0, len = s.length(); i < len; i++) + int index = -1; + for (int brackets = 0, quote = 0; from < to; from++) { - char ch = s.charAt(i); + char ch = s.charAt(from); if (ch == '"') quote++; @@ -621,9 +623,9 @@ public static int indexOfNotInObj(CharSequence s, boolean firstIndex, char... on { if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) { - found = i; if (firstIndex) - return found; + return from; + index = from; } else if ((ch | ' ') == '{') brackets++; @@ -636,7 +638,7 @@ else if ((ch | ' ') == '}') } } } - return found; + return index; } /** @@ -663,8 +665,11 @@ public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind) */ public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, boolean firstIndex) { + int len = s.length(), lenToFind = sequenceToFind.length(); + if (len < lenToFind) + return -1; int found = -1; - for (int i = 0, brackets = 0, quote = 0, match = 0, len = s.length(), lenToFind = sequenceToFind.length(); i < len; i++) + for (int i = 0, brackets = 0, quote = 0, match = 0; i < len; i++) { char ch = s.charAt(i); if (ch == '"') @@ -885,7 +890,7 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO for (Object param : serializer) { - if (postData.length() != 0) + if (postData.length() != 0) postData.append('&'); postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index bc5e442..ffc07a6 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -44,13 +44,18 @@ */ public class BooleanConverter implements DataConverter { - public boolean shorten; + protected boolean shorten; public BooleanConverter() { this(true); } + /** + * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ public BooleanConverter(boolean shorten) { setShorten(shorten); @@ -84,11 +89,21 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); } + /** + * @return If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ public boolean isShorten() { return shorten; } + /** + * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ public void setShorten(boolean shorten) { this.shorten = shorten; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java index d8c276e..624a560 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -46,7 +46,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } catch (Exception e) { - return str.charAt(0); + return str.charAt(1); } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 2c157f5..6c11480 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -31,7 +31,7 @@ public interface DataConverter extends DataParser * @param objToDescribe | Object to generate description for! * @param argsUsedConvert | Array of arguments that were used for converting described object! * - * @return Description for object (should not contains endlines)! + * @return Description for object (should not contain endlines)! * * @since 1.3.0 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 828e550..ce57623 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -247,7 +247,9 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign /** * @param classOfParserToPrecache | Class of parser to precache! * - * @return Int array of 2 signifying the index of where the parser was inserted in parsing cache and converting cache (index 0 = parsing cache index, index 1 = converting cache index) + * @return Int array of 2 signifying the index of where the parser was inserted in parsing cache and converting cache (index 0 = parsing cache index, index 1 = converting cache index). These 2 values should be the same. + * + * @since 1.3.5 */ public int[] preCache(Class classOfParserToPrecache) { @@ -303,8 +305,8 @@ public void resetCache() /** * You can use this to manually set caching arrays. Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other! * - * @param parsingCache | Array of specific parsing cache to use (it can contains some preached parsers to use preferably). This array is supposed to be as long as this registry! - * @param convertingCache | Array of specific converter cache to use (it can contains some preached converters to use preferably). This array is supposed to be as long as this registry! + * @param parsingCache | Array of specific parsing cache to use (it can contains some preached parsers to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! + * @param convertingCache | Array of specific converter cache to use (it can contains some preached converters to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 4f3fa34..10631eb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -259,7 +259,7 @@ else if (ch != 127 && ch != '+') } /** - * @deprecated THIS IS NO LONGER NECESSARY BECAUSE BECAUSE {@link NumberConverter#numberOf(CharSequence, char, int, int, int)} CAN DO THE SAME THING MUCH FASTET! + * @deprecated THIS IS OBSOLET, SLOW AND NO LONGER NECESSARY BECAUSE {@link NumberConverter#numberOf(CharSequence, char, int, int, int)} CAN DO THE SAME THING MUCH FASTET! * * @param num | Number string to format! * diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java similarity index 79% rename from SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java rename to SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index bc300ca..3bead58 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/converters/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -1,4 +1,4 @@ -package org.ugp.serialx.devtools.converters; +package org.ugp.serialx.devtools; import java.util.Map; import java.util.TreeMap; @@ -7,7 +7,6 @@ import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.devtools.SerializationDebugger; /** * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! @@ -115,13 +114,21 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign DataParser parser = parsingCache[i]; if (parser != null) { - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != SerializationDebugger.CONTINUE) + try { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); - return obj; + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } + } + catch (Exception ex) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " (from cache)\n>>\t\"" + str + "\"\tthrew\t" + ex); + return null; } } } @@ -134,15 +141,23 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign if (cls == parser.getClass()) continue registryLoop; - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != SerializationDebugger.CONTINUE) + try + { + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } + } + catch (Exception ex) { - if (parsingCache != null && i < parsingCache.length) - parsingCache[i] = parser; - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); - return obj; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + "\n>>\t\"" + str + "\"\tthrew\t" + ex); + return null; } } diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index 0476abd..bcbc5c4 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -2,6 +2,7 @@ import static org.ugp.serialx.Utils.multilpy; +import java.io.PrintWriter; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -10,13 +11,15 @@ import org.ugp.serialx.Registry; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.devtools.converters.DebugParserRegistry; +import org.ugp.serialx.converters.DataParser; /** * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
* During parsing, type __debug or __debug_yourObject into your code!
* During converting/serializing, serialize your object using {@link DebugWrapper} with your object as argument! * + * @see SerializationDebugger#debug(Serializer) + * * @author PETO * * @since 1.3.5 @@ -25,6 +28,14 @@ public class SerializationDebugger implements DataConverter { public static final String DEBUG_MARK = new String("__debug"); + /** + * Output object that will be used for logging... + * If null, it will be set automatically! + * + * @since 1.3.7 + */ + public static PrintWriter out; + @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { @@ -50,17 +61,20 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. */ public Object printDebugs(DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) { + if (out == null) + out = new PrintWriter(System.err); + String action = objToSerialize == null && strToParse != null ? "Parsing" : "Converting"; - System.err.println("--------------------------------------------- " + action + " Debug ---------------------------------------------"); + out.println("--------------------------------------------- " + action + " Debug ---------------------------------------------"); if (args == null) - System.err.println("------- Available args (args): none (args = null)!"); + out.println("------- Available args (args): none (args = null)!"); else - print("------- Available args (args):", Arrays.asList(args), 0); + print(out, "------- Available args (args):", Arrays.asList(args), 0); if (myHomeRegistry == null) - System.err.println("\n------- Available parsers (myHomeRegistry: null): none!"); + out.println("\n------- Available parsers (myHomeRegistry: null): none!"); else - print("\n------- Available parsers (myHomeRegistry: " + myHomeRegistry.getClass().getName() + "):", myHomeRegistry, 0); + print(out, "\n------- Available parsers (myHomeRegistry: " + myHomeRegistry.getClass().getName() + "):", myHomeRegistry, 0); if (strToParse != null && (strToParse = strToParse.substring(DEBUG_MARK.length())).length() > 0 && (strToParse = strToParse.substring(1)).length() > 0) { @@ -79,14 +93,13 @@ else if (args[99] instanceof Integer && (int) args[99] > 0) objToSerialize = myHomeRegistry.parse(strToParse, args); double t = System.nanoTime(); - if (myHomeRegistry.getParsingCache() == null) - System.err.println("\n------- Paring cache (after process): null (none)"); - else - print("\n------- Paring cache (after process):", Arrays.asList(myHomeRegistry.getParsingCache()), 0); - print("\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); - System.err.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); - System.err.println("String \"" + strToParse + "\" was parsed into:\n\t" + toStringAndCls(objToSerialize)); - System.err.println("\n"); + printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", " (after process)"); + print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + out.println("String \"" + strToParse + "\" was parsed into:\n\t" + toStringAndCls(objToSerialize)); + out.println("\n"); + + out.flush(); return objToSerialize; } @@ -107,31 +120,41 @@ else if (args[99] instanceof Integer && (int) args[99] > 0) strToParse = myHomeRegistry.toString(objToSerialize, args).toString(); double t = System.nanoTime(); - if (myHomeRegistry.getConverterCache() == null) - System.err.println("\n------- Converting cache (after process): null (none)"); - else - print("\n------- Converting cache (after process):", Arrays.asList(myHomeRegistry.getConverterCache()), 0); - print("\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); - System.err.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); - System.err.println("Object " + toStringAndCls(objToSerialize) + " was converted to string:\n" + (strToParse.contains("\n") ? strToParse : "\t" + strToParse)); - System.err.println("\n"); + printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", " (after process)"); + print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + out.println("Object " + toStringAndCls(objToSerialize) + " was converted to string:\n" + (strToParse.contains("\n") ? strToParse : "\t" + strToParse)); + out.println("\n"); + + out.flush(); return strToParse; } - if (myHomeRegistry.getParsingCache() == null) - System.err.println("\n------- Current parsing cache: null (none)"); - else - print("\n------- Current parsing cache:", Arrays.asList(myHomeRegistry.getParsingCache()), 0); - - if (myHomeRegistry.getConverterCache() == null) - System.err.println("\n------- Current parsing cache: null (none)"); - else - print("\n------- Current parsing cache:", Arrays.asList(myHomeRegistry.getConverterCache()), 0); - System.err.println("\n--------------------------------------------- No Results ---------------------------------------------"); - System.err.println("\n"); + printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", ""); + printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", ""); + + out.println("\n--------------------------------------------- No Results ---------------------------------------------"); + if (myHomeRegistry.getParsingCache() != null && myHomeRegistry.getParsingCache().length > 0 || myHomeRegistry.getConverterCache() != null && myHomeRegistry.getConverterCache().length > 0) + out.println("If this is not the expected outcome you can try not using ParserRegistry caching or try to pre-cache some parsers!"); + out.println("\n"); + + out.flush(); return VOID; } + /** + * Helper method for printing contents of {@link ParserRegistry#getParsingCache()}. + * + * @since 1.3.7 + */ + public static void printCacheInfo(PrintWriter out, DataParser[] cache, String cacheType, String additional) + { + if (cache == null) + out.println("\n------- Current " + cacheType + " cache" + additional + ": null (none)"); + else + print(out, "\n------- Current " + cacheType + " cache" + additional + ":", Arrays.asList(cache), 0); + } + /** * @param serializer | Serializer to debug! * @@ -190,19 +213,19 @@ public static String toStringAndCls(Object obj) * * @since 1.3.5 */ - public static void print(String text, List objs, int tabs) + public static void print(PrintWriter out, String text, List objs, int tabs) { - System.err.println(text); + out.println(text); for (int i = 0, i2 = 0; i < objs.size(); i++) { Object o = objs.get(i); String strTbs = multilpy('\t', tabs).toString(); if (o instanceof List) - print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); else if (o instanceof Map) - print(strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); else - System.err.println(multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); + out.println(multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); } } @@ -211,19 +234,19 @@ else if (o instanceof Map) * * @since 1.3.5 */ - public static void print(String text, Map map, int tabs) + public static void print(PrintWriter out, String text, Map map, int tabs) { - System.err.println(text); + out.println(text); for (Entry entry : map.entrySet()) { Object o = entry.getValue(); String strTbs = multilpy('\t', tabs).toString(); if (o instanceof List) - print(strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); else if (o instanceof Map) - print(strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); else - System.err.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); + out.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); } } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index bf12831..09ac8ab 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -217,7 +217,7 @@ protected Appendable appandVar(Appendable source, CharSequence serializedVar, En protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException { source.append(multilpy('\t', tabs)).append(serializedVal); - if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, '/') != -1) + if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) return source; return source.append(','); } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index ea95a34..57a19f9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -361,7 +361,7 @@ protected Appendable appandVar(Appendable source, CharSequence serializedVar, En protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException { source.append(multilpy('\t', tabs)).append(serializedVal); - if (isLast && value instanceof Scope || serializedVal != null && indexOfNotInObj(serializedVal, '/') != -1) + if (isLast && value instanceof Scope || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) return source; return source.append(';'); } diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 0837750..b91ecc9 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -47,7 +47,7 @@ protected Object eval(ParserRegistry registryForParsers, String expr, Object... List cofs = terms[0]; if (cofs.size() <= 1) return CONTINUE; - List oprs = terms[1]; + List oprs = terms[1]; Object cof1 = null, cof2 = null; String opr = null; @@ -67,11 +67,11 @@ protected Object eval(ParserRegistry registryForParsers, String expr, Object... cof1 = registryForParsers.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers); cof1 = cof1 instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1; - cof2 = cofs.remove(index + 1); - if (cof2 instanceof String) - cof2 = registryForParsers.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers); - cof2 = cof2 instanceof ResultWrapper ? ((ResultWrapper) cof2).obj : cof2; - + cof2 = cofs.remove(index + 1); + if (cof2 instanceof String) + cof2 = registryForParsers.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers); + cof2 = cof2 instanceof ResultWrapper ? ((ResultWrapper) cof2).obj : cof2; + opr = oprs.remove(index).toString(); if (opr.charAt(0) == '+') cofs.set(index, new ResultWrapper(addOperator(cof1, cof2))); @@ -93,7 +93,7 @@ else if (opr.charAt(0) == '%') } catch (IndexOutOfBoundsException ex) { - LogProvider.instance.logErr("Missing coefficient in \"" + expr + "\"!", ex); + LogProvider.instance.logErr("Missing coefficient in \"" + expr + "\"!", null); } catch (ArithmeticException ex) { @@ -123,7 +123,7 @@ public Object subOperator(Object cof, Object cof2) return sub(toNum(cof), toNum(cof2)); } - /** + /** * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign) supposed to be returned! * * @since 1.3.2 @@ -133,7 +133,7 @@ public Object multOperator(Object cof, Object cof2, int sign) return mult(toNum(cof), toNum(cof2), sign); } - /** + /** * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign) supposed to be returned! * * @since 1.3.2 @@ -143,8 +143,8 @@ public Object divOperator(Object cof, Object cof2, int sign) return div(toNum(cof), toNum(cof2), sign); } - /** - * @return Modulation of cod and cof2 (cof % cof2) supposed to be returned! + /** + * @return Modulation of cod and cof2 (cof % cof2) supposed to be returned! * * @since 1.3.2 */ @@ -154,7 +154,7 @@ public Object modOperator(Object cof, Object cof2) } /** - * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign)) supposed to be returned! + * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign)) supposed to be returned! * * @since 1.3.2 */ @@ -235,7 +235,7 @@ public static Object sub(Object cof, Object cof2) return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); } - + if (cof instanceof Collection) { if (cof2 instanceof Collection) @@ -247,6 +247,17 @@ else if (cof2.getClass().isArray()) return cof; } + if (cof instanceof Scope) + { + if (cof2 instanceof Collection) + ((Scope) cof).values().removeAll((Collection) cof2); + else if (cof2.getClass().isArray()) + ((Scope) cof).values().removeAll(Arrays.asList(cof2)); + else + ((Scope) cof).values().remove(cof2); + return cof; + } + return null; } @@ -341,7 +352,6 @@ else if (cof instanceof Integer || cof2 instanceof Integer) /** * * @param str | String to split! - * @param operatos | If true, list of spited operators will be returned otherwise terms split after each operator. * @param oprs | Operators to use as a splitters. * * @return List of terms splitted according to inserted arguments! For example getTerm("5 + 6", true, '+') will return [+], while getTerm("5 + 6", false, '+') will return [5, 6]! @@ -349,7 +359,7 @@ else if (cof instanceof Integer || cof2 instanceof Integer) * @since 1.3.0 */ @SuppressWarnings("unchecked") - public static List[] getTerms(String str, char... oprs) + public static List[] getTerms(CharSequence str, char... oprs) { List[] ret = new ArrayList[] {new ArrayList<>(), new ArrayList<>()}; //cofs, ops @@ -441,7 +451,7 @@ else if (oldCh <= 32 && isCof == 1) } /** - * @return null -> 0, bool ? 1 : 0 + * @return null -> 0, bool ? 1 : 0. Otherwise obj. * * @since 1.3.0 */ @@ -449,9 +459,9 @@ public static Object toNum(Object obj) { if (obj == null) return 0; - else if (obj instanceof Boolean) + if (obj instanceof Boolean) return (boolean) obj ? 1 : 0; - else if (obj instanceof Character) + if (obj instanceof Character) return (int) (char) obj; return obj; } diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 7509862..b60d778 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -13,7 +13,7 @@ import org.ugp.serialx.converters.imports.ImportsProvider; /** - * This parser provides comparison operators to compare 2 objects! For example 6 > 5 or 5 == 5 returns true! + * This parser provides comparison operators, > < >= <= == === != !=== and instanceof, to compare 2 objects! For example 6 > 5, 1 < 5 or 5 == 5 returns true! * * @author PETO * @@ -24,42 +24,43 @@ public class ComparisonOperators implements DataParser @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - int index = -1; - if (str.length() > 2 && (indexOfNotInObj(str, '>', '<', '!', '=') > -1 || (index = indexOfNotInObj(str, " instanceof ")) > -1)) + int len; + if ((len = str.length()) < 3) + return CONTINUE; + + int index, op; + if ((index = indexOfNotInObj(str, '<', '>', '=')) > -1) { - if (index > -1) + if ((op = str.charAt(index)) != '=') // > < { - try - { - return ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(index+12).trim()).isInstance(myHomeRegistry.parse(str.substring(0, index).trim(), args)); - } - catch (Exception e) - { - LogProvider.instance.logErr("Unable to check if object " + str.substring(0, index).trim() + " is instance of class \"" + str.substring(index+12).trim() + "\" because there is no such a class!", e); - return null; - } + boolean orEqual = index+1 < len && str.charAt(index+1) == '='; + return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), op == '>', orEqual); } - else if ((index = str.indexOf("!=")) > -1) + + if (/*op == '=' &&*/ str.charAt(index+1) == '=') // == { - boolean isTripple = str.charAt(index+2) == '='; - return !equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + boolean isTripple = index+2 < len && str.charAt(index+2) == '='; + return equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); } - else if ((index = str.indexOf("==")) > -1) + if (/*op == '=' &&*/ str.charAt(--index) == '!') // != { - boolean isTripple = str.charAt(index+2) == '='; - return equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + boolean isTripple = index+2 < len && str.charAt(index+2) == '='; + return !equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); } - else if ((index = str.indexOf('<')) > -1) + //System.out.println(str); + } + + if ((index = indexOfNotInObj(str, " instanceof ")) > -1) + { + try { - boolean orEqual = str.charAt(index+1) == '='; - return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), false, orEqual); + return ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(index+12).trim()).isInstance(myHomeRegistry.parse(str.substring(0, index).trim(), args)); } - else if ((index = str.indexOf('>')) > -1) + catch (Exception e) { - boolean orEqual = str.charAt(index+1) == '='; - return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), true, orEqual); + LogProvider.instance.logErr("Unable to check if object " + str.substring(0, index).trim() + " is instance of class \"" + str.substring(index+12).trim() + "\" because there is no such a class!", e); + return null; } - //System.out.println(str); } //double t = System.nanoTime(); //System.out.println((t-t0)/1000000); diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 57fc84c..e3ad5cf 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -17,22 +17,21 @@ public class ConditionalAssignmentOperators implements DataParser @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - if (str.length() > 2 && indexOfNotInObj(str, '?') > -1) + int index, ternIfIndex; + if (str.length() > 2 && (index = indexOfNotInObj(str, '?')) > -1) { - int index = indexOfOne(str, 0, '?'); - if (index > -1) + if ((ternIfIndex = indexOfOne(str, index, '?')) > -1) //?: { try { - String last = str.substring(index+1), first = str.substring(0, index); + String last = str.substring((index = ternIfIndex)+1), first = str.substring(0, index); boolean condition = (boolean) LogicalOperators.toBool(myHomeRegistry.parse(first.trim(), args)); if ((index = indexOfTernaryElse(last, 1, '?', ':')) > -1) { first = last.substring(0, index); return condition ? myHomeRegistry.parse(first.trim(), args) : (last = last.substring(index+1).trim()).isEmpty() ? VOID : myHomeRegistry.parse(last, args); } - else - return condition ? myHomeRegistry.parse(last.trim(), args) : VOID; + return condition ? myHomeRegistry.parse(last.trim(), args) : VOID; } catch (ClassCastException ex) { @@ -41,10 +40,10 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } } - if ((index = str.indexOf("??")) > -1) + if (str.charAt(index+1) == '?') //?? { - Object obj = myHomeRegistry.parse(str.substring(0, index).trim(), args); - if (obj != null) + Object obj ; + if ((obj = myHomeRegistry.parse(str.substring(0, index).trim(), args)) != null) return obj; String next = str.substring(index+2); @@ -57,17 +56,17 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } /** - * @param str - * @param defaultCountOfConfitions - * @param tenraryTokens + * @param str | Source string to search. + * @param defaultCountOfConfitions | How many condition operators (tenraryTokens[0]) are expected. Should be 1 in most cases. + * @param tenraryTokens | Characters representing parts of ternary operator. Index 0 should be '?' and index 1 should be ':'. * - * @return + * @return Return index of else branch in ternary operator expression or -1 if there is no else branch! * * @since 1.3.5 */ public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) { - for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, quote = 0, brackets = 0; i < len; i++) + for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, quote = 0, brackets = 0; i < len; i++) { char ch = str.charAt(i); if (ch == '\"') @@ -94,11 +93,11 @@ else if (quote % 2 == 0 && brackets == 0) } /** - * @param str - * @param from - * @param oneChar + * @param str | String to search. + * @param from | Beginning index. Should be 0 in most cases. + * @param oneChar | Single character that you want to find. * - * @return + * @return Index of oneChar if there is only one in a row! * * @since 1.3.5 */ diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index 9bd7cb6..5e60f17 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -1,11 +1,9 @@ package org.ugp.serialx.converters.operators; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.converters.operators.ArithmeticOperators.getTerms; -import java.util.List; - -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; /** @@ -20,80 +18,47 @@ public class LogicalOperators implements DataParser @Override public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) { - if (s.length() > 2 && indexOfNotInObj(s, '&', '|', '^') > -1) + int len; + if ((len = s.length()) < 3) + return CONTINUE; + + Object result = CONTINUE; + int i = 0, index; + do { - List[] terms = getTerms(s, '&', '|', '^'); - List cofs = terms[0]; - if (cofs.size() <= 1) - return CONTINUE; - - List oprs = terms[1]; + if ((index = indexOfNotInObj(s, i, len, true, '&', '|', '^')) == -1) + return result; - Object cof1 = null, cof2 = null, opr = null; - try - { - for (int i = 0, index = 0, size = oprs.size(); i < size; index = 0, i++) - { - opr = oprs.remove(index); - if (opr.equals("&&")) - { - cof1 = cofs.get(index); - if (cof1 instanceof String) - cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); - if (cof1.equals(false)) - { - cofs.remove(index + 1); - cofs.set(index, false); - } - else - { - cof2 = cofs.remove(index + 1); - if (cof2 instanceof String) - cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); - cofs.set(index, andOperator(cof1, cof2)); - } - } - else if (opr.equals("||")) - { - cof1 = cofs.get(index); - if (cof1 instanceof String) - cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); - if (cof1.equals(true)) - { - return true; - } - else - { - cof2 = cofs.remove(index + 1); - if (cof2 instanceof String) - cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); - cofs.set(index, orOperator(cof1, cof2)); - } - } - else if (opr.equals("^")) - { - cof1 = cofs.get(index); - if (cof1 instanceof String) - cof1 = myHomeRegistry.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, args); - - cof2 = cofs.remove(index + 1); - if (cof2 instanceof String) - cof2 = myHomeRegistry.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, args); - cofs.set(index, xorOperator(cof1, cof2)); - } - } - } - catch (ClassCastException ex) + int op; + if ((op = s.charAt(i = index)) != '^' && (++i >= len || s.charAt(i) != op)) // Ensure && and || and refuse & and | + continue; + + if (result == CONTINUE) // Beginning + result = myHomeRegistry.parse(s.substring(0, index).trim(), args); + + int nextOpIndex; + if ((nextOpIndex = indexOfNotInObj(s, ++i, len, true, '&', '|', '^')) == -1) + nextOpIndex = len; + + if (op == '&') { - LogProvider.instance.logErr("Logical operator " + opr + " is undefined between " + cof1.getClass().getName() + " and " + cof2.getClass().getName() + "!", ex); + if (!FALSE.equals(result)) + result = andOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); } - catch (IndexOutOfBoundsException e) + else if (op == '|') { - LogProvider.instance.logErr("Missing coefficient in \"" + s + "\"!", e); + if (TRUE.equals(result)) + return TRUE; + result = orOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); } - return cofs.get(0); + else + result = xorOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + + i = nextOpIndex; } - return CONTINUE; + while (i < len); + + return result; } /** @@ -127,7 +92,7 @@ public Object xorOperator(Object obj1, Object obj2) } /** - * @return null -> false or if number > 0 + * @return null -> false or if number > 0. Otherwise obj. * * @since 1.3.0 */ @@ -135,18 +100,18 @@ public static Object toBool(Object obj) { if (obj == null) return false; - else if (obj instanceof Number) - return ((Number) obj).doubleValue() > 0; - else if (obj instanceof Character) - return (char) obj > 0; - /*else if (obj instanceof Map) + if (obj instanceof Number) + return ((Number) obj).doubleValue() != 0; + if (obj instanceof Character) + return (char) obj != 0; + /*if (obj instanceof Map) return !((Map) obj).isEmpty(); - else if (obj instanceof Collection) + if (obj instanceof Collection) return !((Collection) obj).isEmpty(); - else if (obj instanceof Scope) + if (obj instanceof Scope) return !((Scope) obj).isEmpty(); - else if (obj.getClass().isArray()) + if (obj.getClass().isArray()) return Array.getLength(obj) > 0;*/ return obj; } -} +} \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java index d59f941..f644357 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -4,7 +4,8 @@ import org.ugp.serialx.converters.DataParser; /** - * This parser provides ability to negate stuff! For example !true returns false! + * This parser provides ability to negate stuff! For example !true returns false!
+ * This include classic numeric negation - and logical negation ! operators. * * @author PETO * @@ -16,11 +17,11 @@ public class NegationOperator implements DataParser public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { int ch, len = str.length(); - if (len > 0 && ((ch = str.charAt(0)) == '-' || ch == '!')) + if (len > 0 && ((ch = str.charAt(0)) == '!' || ch == '-')) { int negCount = 1; for (int i = negCount; i < len; i++) - if ((ch = str.charAt(i)) == '-' || ch == '!') + if ((ch = str.charAt(i)) == '!' || ch == '-') negCount++; else break; @@ -28,7 +29,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) Object obj = myHomeRegistry.parse(str.substring(negCount), args); if (negCount % 2 == 0) return obj; - Object neg = notOperator(obj); + Object neg = ch == '!' ? logicalNotOperator(obj) : notOperator(obj); if (obj == neg && !(obj instanceof Number && ((Number) obj).intValue() == 0)) LogProvider.instance.logErr("Unable to nagete \"" + obj + "\" because object of \"" + obj.getClass().getName() + "\" cant be negated!", null); return neg; @@ -38,7 +39,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) /** - * @param obj | Object to negate! + * @param obj | Object to negate! Numeric in nature or an object! * * @return Negated object supposed to be returned or same object as argument if object can't be negated! Only numbers and booleans can be negated! * @@ -49,6 +50,19 @@ public Object notOperator(Object obj) return negate(obj); } + /** + * @param obj | Object to negate! Should be boolean! + * + * @return Negated object supposed to be returned or same object as argument if object can't be negated! Should, but do not strictly has to be boolean!
+ * Node: By default it has same behavior as {@link NegationOperator#notOperator(Object)} but it can be overridden! + * + * @since 1.3.7 + */ + public Object logicalNotOperator(Object obj) + { + return negate(obj); + } + /** * @param obj | Object to negate! * From 7cce36be443eb13eec9e2406ba711a8a98bc0bc6 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 2 Jul 2024 14:47:59 +0200 Subject: [PATCH 29/75] refactoring AritmeticOperators, GenericScope is now Collection! --- .../java/org/ugp/serialx/GenericScope.java | 115 +++++++++++--- .../src/main/java/org/ugp/serialx/Scope.java | 4 +- .../main/java/org/ugp/serialx/Serializer.java | 2 +- .../ugp/serialx/converters/DataParser.java | 12 +- .../ugp/serialx/protocols/ScopeProtocol.java | 2 +- .../protocols/SerializationProtocol.java | 3 +- .../serialx/devtools/DebugParserRegistry.java | 12 +- .../juss/converters/VariableConverter.java | 2 +- .../operators/ArithmeticOperators.java | 144 +++++++++++------- 9 files changed, 200 insertions(+), 96 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 7cec162..359e51d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -22,7 +22,7 @@ /** - * This is some kind of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
+ * This collection is some sort of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
* Note: Variables are managed and accessed classically via {@link Map} methods such as put(KeyT key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
* Also this is java representation of JUSS GenericScope group such as: *
@@ -35,12 +35,12 @@
  * 
  * @author PETO
  * 
- * @since 1.2.0
+ * @since 1.3.5
  * 
  * @param  generic type of variables key.
  * @param  generic type of variables value and independent value.
  */
-public class GenericScope implements Iterable, Cloneable, Serializable
+public class GenericScope implements Collection, Cloneable, Serializable
 {
 	private static final long serialVersionUID = 5717775602991055386L;
 	
@@ -108,7 +108,7 @@ else if (obj instanceof Collection)
 		else if (obj instanceof Map)
 			return valuesCount() <= 0 && variables().equals(obj);
 		else if (obj != null && obj.getClass().isArray())
-			return variablesCount() <= 0 && Objects.deepEquals(toValArray(), Utils.fromAmbiguousArray(obj));
+			return variablesCount() <= 0 && Objects.deepEquals(toArray(), Utils.fromAmbiguousArray(obj));
 		return super.equals(obj);
 	}
 	
@@ -365,12 +365,28 @@ public boolean containsVariable(KeyT variableKey)
 	}
 	
 	/**
-	 * @param value | Objecthe value.
+	 * @param value | Object the independent value.
+	 * 
+	 * @return True if independent value was found in this scope.
+	 * 
+	 * @since 1.3.7
+	 */
+	@Override
+	public boolean contains(Object value) 
+	{
+		return values().contains(value);
+	}
+	
+	/**
+	 * @deprecated USE {@link GenericScope#contains(Object)} instead!
+	 * 
+	 * @param value | Object the value.
 	 * 
 	 * @return True if independent value was found in this scope.
 	 * 
 	 * @since 1.2.0
 	 */
+	@Deprecated
 	public boolean containsIndependentValue(ValT value) 
 	{
 		return values().contains(value);
@@ -417,6 +433,7 @@ public  V get(int valueIndex, Class cls) throws Exception
 	 * 
 	 * @since 1.2.0
 	 */
+	@Override
 	public boolean add(ValT value)
 	{
 		boolean result = values().add(value);
@@ -432,11 +449,12 @@ public boolean add(ValT value)
 	 * 
 	 * @since 1.2.0
 	 */
-	public boolean addAll(Collection values)
+	@Override
+	public boolean addAll(Collection values)
 	{
 		if (values.isEmpty())
 			return false;
-		return values().addAll(values);
+		return values().addAll((Collection) values);
 	}
 	
 	/**
@@ -451,6 +469,45 @@ public boolean addAll(@SuppressWarnings("unchecked") ValT... values)
 		return addAll(Arrays.asList(values));
 	}
 	
+	/**
+	 * @param values | Independent values to check.
+	 * 
+	 * @return True all provided values are contained in this scope as independent values!
+	 * 
+	 * @since 1.3.7
+	 */
+	@Override
+	public boolean containsAll(Collection values) 
+	{
+		return values().containsAll(values);
+	}
+
+	/**
+	 * @param values | Independent values to check.
+	 * 
+	 * @return {@link Collection#removeAll(Collection)} for the independent values,,,
+	 * 
+	 * @since 1.3.7
+	 */
+	@Override
+	public boolean removeAll(Collection values)
+	{
+		return values().removeAll(values);
+	}
+
+	/**
+	 * @param values | Independent values to check.
+	 * 
+	 * @return {@link Collection#retainAll(Collection)} for the independent values,,,
+	 * 
+	 * @since 1.3.7
+	 */
+	@Override
+	public boolean retainAll(Collection values)
+	{
+		return values().retainAll(values);
+	}
+	
 	/**
 	 * @param scopeValueIndex | Index of sub-scopes value.
 	 * 
@@ -521,7 +578,7 @@ public  T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws
 		SerializationProtocol pro = protocolsToUse == null ? null : protocolsToUse.GetProtocolFor(objClass, SerializationProtocol.MODE_DESERIALIZE);
 		if (pro != null)
 		{
-			T obj = pro.unserialize(objClass, this.variablesCount() > 0 ? new Object[] {this} : this.toValArray());
+			T obj = pro.unserialize(objClass, this.variablesCount() > 0 ? new Object[] {this} : this.toArray());
 			if (obj != null)
 				return obj;
 		}
@@ -680,14 +737,27 @@ public ValT remove(int valueIndex)
 		return values().remove(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex);
 	}
 	
+	/**
+	 * @param independentValue | Independent value to remove!
+	 * 
+	 * @return Value of variable that was removed!
+	 * 
+	 * @since 1.3.7
+	 */
+	@Override
+	public boolean remove(Object independentValue)
+	{
+		return values().remove(independentValue);
+	}
+	
 	/**
 	 * @param variableKey | Name of variable to remove!
 	 * 
 	 * @return Value of variable that was removed!
 	 * 
-	 * @since 1.3.2
+	 * @since 1.3.7
 	 */
-	public ValT remove(KeyT variableKey)
+	public ValT removeVariable(KeyT variableKey)
 	{
 		return variables().remove(variableKey);
 	}
@@ -699,6 +769,7 @@ public ValT remove(KeyT variableKey)
 	 * 
 	 * @since 1.3.5
 	 */
+	@Override
 	public void clear()
 	{
 		variables().clear();
@@ -712,7 +783,7 @@ public void clear()
 	 */
 	@SuppressWarnings("unchecked")
 	public GenericScope inheritParent()
-	{ 
+	{
 		GenericScope parent = getParent();
 		if (parent != null)
 			variables().putAll((Map) parent.variables());
@@ -765,8 +836,11 @@ public int variablesCount()
 	
 	/**
 	 * @return Total number of variables and independent values of this scope! (vvaluesCount() + variablesCount())
+	 * 
+	 * @since 1.3.7 (before 1.3.7 known as totalSize)
 	 */
-	public int totalSize()
+	@Override
+	public int size()
 	{
 		return valuesCount() + variablesCount();
 	}
@@ -776,9 +850,10 @@ public int totalSize()
 	 * 
 	 * @since 1.2.0
 	 */
+	@Override
 	public boolean isEmpty()
 	{
-		return totalSize() <= 0;
+		return size() <= 0;
 	}
 	
 	/**
@@ -838,22 +913,24 @@ public List toValList()
 	 * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent!
 	 * Modifying this list will not affect this {@link GenericScope} object!
 	 * 
-	 * @since 1.2.0
+	 * @since 1.3.7 (before 1.3.7 known as toValArray)
 	 */
-	public Object[] toValArray()
+	@Override
+	public Object[] toArray() 
 	{
 		return values().toArray();
 	}
-	
+
 	/**
 	 * @param vals | Array to store independent values into!
 	 * 
 	 * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent!
 	 * Modifying this list will not affect this {@link GenericScope} object!
 	 * 
-	 * @since 1.3.5
+	 * @since 1.3.7 (before 1.3.7 known as toValArray)
 	 */
-	public  V[] toValArray(V[] vals)
+	@Override
+	public  T[] toArray(T[] vals) 
 	{
 		return values().toArray(vals);
 	}
@@ -874,7 +951,7 @@ public List toUnifiedList()
 	}
 	
 	/**
-	 * @return Values of this scope. These are not the values of keys these are values that have no key. You can access them via {@link GenericScope#get(int)}!
+	 * @return Independent values of this scope. These are not the values of keys these are values that have no key. You can access them via {@link GenericScope#get(int)}!
 	 * Note: Editing this List will affect this scope!
 	 * 
 	 * @since 1.2.0
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
index eba21de..ca80662 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
@@ -22,7 +22,7 @@
 
 	
 /**
- * This is some kind of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object. 
+ * This collection is some sort of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
* Note: Variables are managed and accessed classically via {@link Map} methods such as put(String key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
* Also this is java representation of JUSS Scope group such as: *
@@ -1082,7 +1082,7 @@ public static  T intoNew(Class objCls, GenericScope fro
 		if (objCls.isArray())
 		{
 			if (objCls.getComponentType() == Object.class)
-				return (T) fromScope.toValArray();
+				return (T) fromScope.toArray();
 			
 			return (T) into(Array.newInstance(objCls.getComponentType(), fromScope.valuesCount()), fromScope, fieldNamesToUse);
 		}
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
index 3dcd9e9..8b0fc6b 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java
@@ -35,7 +35,7 @@
 import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry;
 
 /**
- * {@link org.ugp.serialx.Serializer} is powerful utility class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s.
+ * {@link org.ugp.serialx.Serializer} is powerful abstract class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s.
  * This class itself is responsible for formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage!
  * It is instance of {@link Scope} so we can say that this is scope that can serialize itself using system of already mentioned {@link DataParser} and {@link SerializationProtocol}!
  * 
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
index ce57623..e55a673 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java
@@ -213,21 +213,19 @@ public Object parse(String str, Object... args)
 		 * 
 		 * @since 1.3.5
 		 */
-		public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args)
+		public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args)
 		{
 			Object obj = null; 
 			if (parsingCache != null)
 				for (DataParser parser : parsingCache)
-					if (parser != null && (obj = parser.parse(this, str, args)) != CONTINUE)
+					if (parser != null && (ignore == null || ignore != parser.getClass()) && (obj = parser.parse(this, str, args)) != CONTINUE)
 						return obj; 
 			
-			registryLoop: for (int i = 0, size = size(); i < size; i++)
+			for (int i = 0, size = size(); i < size; i++)
 			{
 				DataParser parser = get(i);
-				if (ignore != null)
-					for (Class cls : ignore) 
-						if (cls == parser.getClass())
-							continue registryLoop;
+				if (ignore != null && ignore == parser.getClass())
+					continue;
 
 				if ((obj = parser.parse(this, str, args)) != CONTINUE)
 				{
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java
index aae4ce0..e591c13 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java
@@ -33,7 +33,7 @@ public Object[] serialize(GenericScope object) throws Exception
 		{
 			if (objectClass == args[0].getClass())
 				return (GenericScope) args[0];
-			return objectClass.getConstructor(Map.class, Object[].class).newInstance(((GenericScope) args[0]).toVarMap(), ((GenericScope) args[0]).toValArray());
+			return objectClass.getConstructor(Map.class, Object[].class).newInstance(((GenericScope) args[0]).toVarMap(), ((GenericScope) args[0]).toArray());
 		}
 		return objectClass.getConstructor(Map.class, Object[].class).newInstance(new HashMap<>(), args);
 	}
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java
index 2b8d50a..20e98a3 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java
@@ -293,7 +293,8 @@ public ProtocolRegistry clone()
 		@Override
 		public void add(int index, SerializationProtocol element) 
 		{
-			if (GetProtocolFor(element.applicableFor()) != null && element.applicableFor() != Object.class)
+			SerializationProtocol existing;
+			if ((existing = GetProtocolFor(element.applicableFor(), element.getMode())) != null && element.applicableFor() == existing.applicableFor())
 				LogProvider.instance.logErr("Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null);
 			addDuplicatively(index, element);
 		}
diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java
index 3bead58..5d5cc77 100644
--- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java
+++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java
@@ -98,7 +98,7 @@ public CharSequence toString(Object obj, Object... args) {
 	}
 	
 	@Override
-	public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ignore, Object... args) 
+	public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) 
 	{
 		int iterationIndex = 0;
 		if (args.length > 99 && args[99] instanceof Integer)
@@ -112,7 +112,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign
 			for (int i = 0; i < parsingCache.length; i++)
 			{
 				DataParser parser = parsingCache[i];
-				if (parser != null)
+				if (parser != null && (ignore == null || ignore != parser.getClass()))
 				{
 					try 
 					{
@@ -133,13 +133,11 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class[] ign
 				}
 			}
 	
-		registryLoop: for (int i = 0, size = size(); i < size; i++)
+		for (int i = 0, size = size(); i < size; i++)
 		{
 			DataParser parser = get(i);
-			if (ignore != null)
-				for (Class cls : ignore) 
-					if (cls == parser.getClass())
-						continue registryLoop;
+			if (ignore != null && ignore == parser.getClass())
+				continue;
 
 			try 
 			{
diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
index a18a471..7e0038c 100644
--- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
+++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java
@@ -171,7 +171,7 @@ public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, St
 		if (source instanceof GenericScope)
 		{
 			if (val == VOID)
-				return ((GenericScope) source).remove(member);
+				return ((GenericScope) source).removeVariable(member);
 			return ((GenericScope) source).put(genericVar ? myHomeRegistry.parse(member, true, null, args) : member, val);
 		}
 		return VOID;
diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java
index b91ecc9..b3cc5fd 100644
--- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java
+++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java
@@ -1,17 +1,20 @@
 package org.ugp.serialx.converters.operators;
 
+import static java.util.Arrays.asList;
 import static org.ugp.serialx.Utils.fastReplace;
+import static org.ugp.serialx.Utils.fromAmbiguousArray;
 import static org.ugp.serialx.Utils.isOneOf;
+import static org.ugp.serialx.Utils.mergeArrays;
 import static org.ugp.serialx.Utils.multilpy;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
+import java.util.ListIterator;
 
+import org.ugp.serialx.GenericScope;
 import org.ugp.serialx.LogProvider;
-import org.ugp.serialx.Scope;
-import org.ugp.serialx.Utils;
 import org.ugp.serialx.converters.DataParser;
 
 /**
@@ -23,7 +26,7 @@
  */
 public class ArithmeticOperators implements DataParser
 {
-	protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"};
+//	protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"};
 	
 	@Override
 	public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) 
@@ -38,53 +41,62 @@ public Object parse(ParserRegistry myHomeRegistry, String s, Object... args)
 	 * 
 	 * @since 1.3.0
 	 */
+	@SuppressWarnings("unchecked")
 	protected Object eval(ParserRegistry registryForParsers, String expr, Object... argsForParsers)
 	{
 		while (expr.contains("++") || expr.contains("--") || expr.contains("+-") || expr.contains("-+"))
 			expr = fastReplace(fastReplace(fastReplace(fastReplace(expr, "-+", "-"), "+-", "-"), "--", "+"), "++", "+");
 
-		List[] terms = getTerms(expr, '+', '-', '*', '/', '%');
-		List cofs = terms[0];
+		List[] terms = getAndParseTerms(expr, registryForParsers, argsForParsers, getClass(), '+', '-', '*', '/', '%');
+		ArrayList cofs = (ArrayList) terms[0];
 		if (cofs.size() <= 1)
-			return CONTINUE;
-		List oprs = terms[1];
+			return cofs.get(0);
+		LinkedList oprs = (LinkedList) terms[1];
 
 		Object cof1 = null, cof2 = null;
 		String opr = null;
 		try 
 		{
-			for (int i = 0, index = -1, orderIndex = 0, size = oprs.size(); i < size; index = -1, i++) 
+			for (int i = 0, index = 0, oprsSize = oprs.size(), currentOpPrio = 2; i < oprsSize; index = 0, i++)
 			{
-				for (String adept : priority1Oprs)
-					if ((orderIndex = oprs.indexOf(adept)) > -1 && (index == -1 || orderIndex < index))
-						index = orderIndex;
-				for (String adept : priority2Oprs)
-					if ((orderIndex = oprs.indexOf(adept)) > -1)
-						index = orderIndex;
+				opPrioCheck: //Yes yes... this is quite a shenanigan but it is fast...
+				{
+					for (; currentOpPrio > 0; currentOpPrio--)
+					{
+						for (ListIterator iter = oprs.listIterator(); iter.hasNext();) 
+						{
+							if (getOperatorPriority(opr = iter.next()) == currentOpPrio)
+							{
+								iter.remove();
+								index = iter.nextIndex();
+								break opPrioCheck;
+							}
+						}
+						opr = null;
+					}
+					opr = oprs.poll(); //opr = null;
+				}
 
-				cof1 = cofs.get(index = index < 0 ? 0 : index);
-				if (cof1 instanceof String)
-					cof1 = registryForParsers.parse(cof1.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers);
-				cof1 = cof1 instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1;
-	
+				cof1 = cofs.get(index);
 				cof2 = cofs.remove(index + 1);
-				if (cof2 instanceof String)
-					cof2 = registryForParsers.parse(cof2.toString().trim(), i > 0, new Class[] {getClass()}, argsForParsers);
-				cof2 = cof2 instanceof ResultWrapper ? ((ResultWrapper) cof2).obj : cof2;
 
-				opr = oprs.remove(index).toString();
-				if (opr.charAt(0) == '+')
-					cofs.set(index, new ResultWrapper(addOperator(cof1, cof2)));
-				else if (opr.charAt(0) == '-')
-					cofs.set(index, new ResultWrapper(subOperator(cof1, cof2)));
-				else if (opr.startsWith("**"))
-					cofs.set(index, new ResultWrapper(powOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)));
-				else if (opr.charAt(0) == '*')
-					cofs.set(index, new ResultWrapper(multOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)));
-				else if (opr.charAt(0) == '/')
-					cofs.set(index, new ResultWrapper(divOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)));
-				else if (opr.charAt(0) == '%')
-					cofs.set(index, new ResultWrapper(modOperator(cof1, cof2)));
+				switch (opr.charAt(0))
+				{
+					case '+':
+						cofs.set(index, addOperator(cof1, cof2)); break;
+					case '-':
+						cofs.set(index, subOperator(cof1, cof2)); break;
+					case '*':
+						if (opr.length() > 1 && opr.charAt(1) == '*')
+						{
+							cofs.set(index, powOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break;
+						}
+						cofs.set(index, multOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break;
+					case '/':
+						cofs.set(index, divOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break;
+					case '%':
+						cofs.set(index, modOperator(cof1, cof2)); break;
+				}
 			}
 		}
 		catch (ClassCastException ex)
@@ -100,7 +112,22 @@ else if (opr.charAt(0) == '%')
 			LogProvider.instance.logErr(ex.getMessage(), ex);
 		}
 		
-		return (cof1 = cofs.get(0)) instanceof ResultWrapper ? ((ResultWrapper) cof1).obj : cof1;
+		return cofs.get(0);
+	}
+	
+	public int getOperatorPriority(String op)
+	{
+		switch (op.charAt(0))
+		{
+			case '+':
+			case '-':
+				return 0; // Low
+			case '*':
+				if (op.length() > 1 && op.charAt(1) == '*')
+					return 2; // High  **
+			default:
+				return 1; // Medium  * / %
+		}
 	}
 	
 	/** 
@@ -186,29 +213,29 @@ public static Object add(Object cof, Object cof2)
 		}
 		
 		if (cof.getClass().isArray())
-			return Utils.mergeArrays(cof, cof2);
+			return mergeArrays(cof, cof2);
 		
 		if (cof instanceof Collection)
 		{
 			if (cof2 instanceof Collection)
 				((Collection) cof).addAll(((Collection) cof2));
 			else if (cof2.getClass().isArray())
-				((Collection) cof).addAll(Arrays.asList(Utils.fromAmbiguousArray(cof2)));
+				((Collection) cof).addAll(asList(fromAmbiguousArray(cof2)));
 			else 
 				((Collection) cof).add(cof2);
 			return cof;
 		}
 		
-		if (cof instanceof Scope)
+		if (cof instanceof GenericScope)
 		{
-			if (cof2 instanceof Scope)
-				((Scope) cof).addAll(((Scope) cof2));
+			if (cof2 instanceof GenericScope)
+				((GenericScope) cof).addAll(((GenericScope) cof2));
 			else if (cof2 instanceof Collection)
-				((Scope) cof).addAll((Collection) cof2);
+				((GenericScope) cof).addAll((Collection) cof2);
 			else if (cof2.getClass().isArray())
-				((Scope) cof).addAll(Utils.fromAmbiguousArray(cof2));
+				((GenericScope) cof).addAll(fromAmbiguousArray(cof2));
 			else 
-				((Scope) cof).add(cof2);
+				((GenericScope) cof).add(cof2);
 			return cof;
 		}
 		return String.valueOf(cof) + String.valueOf(cof2);
@@ -241,20 +268,20 @@ public static Object sub(Object cof, Object cof2)
 			if (cof2 instanceof Collection)
 				((Collection) cof).removeAll(((Collection) cof2));
 			else if (cof2.getClass().isArray())
-				((Collection) cof).removeAll(Arrays.asList(Utils.fromAmbiguousArray(cof2)));
+				((Collection) cof).removeAll(asList(fromAmbiguousArray(cof2)));
 			else 
 				((Collection) cof).remove(cof2);
 			return cof;
 		}
 		
-		if (cof instanceof Scope)
+		if (cof instanceof GenericScope)
 		{
 			if (cof2 instanceof Collection)
-				((Scope) cof).values().removeAll((Collection) cof2);
+				((GenericScope) cof).values().removeAll((Collection) cof2);
 			else if (cof2.getClass().isArray())
-				((Scope) cof).values().removeAll(Arrays.asList(cof2));
+				((GenericScope) cof).values().removeAll(asList(cof2));
 			else 
-				((Scope) cof).values().remove(cof2);
+				((GenericScope) cof).values().remove(cof2);
 			return cof;
 		}
 		
@@ -356,15 +383,15 @@ else if (cof instanceof Integer || cof2 instanceof Integer)
 	 * 
 	 * @return List of terms splitted according to inserted arguments! For example getTerm("5 + 6", true, '+') will return [+], while getTerm("5 + 6", false, '+') will return [5, 6]! 
 	 *
-	 * @since 1.3.0
+	 * @since 1.3.7 (originally getTerms since 1.3.0)
 	 */
 	@SuppressWarnings("unchecked")
-	public static List[] getTerms(CharSequence str, char... oprs)
+	public static List[] getAndParseTerms(String str, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs)
 	{
-		List[] ret = new ArrayList[] {new ArrayList<>(), new ArrayList<>()}; //cofs, ops
-		
-		StringBuilder[] sbs = {new StringBuilder(), new StringBuilder()}; //cofs, ops
+		List[] ret = new List[] {new ArrayList(), new LinkedList()}; //cofs, ops
 		
+		StringBuilder[] sbs = {new StringBuilder(), new StringBuilder()}; //cofs, ops TODO
+
 		int i = 0, type = 0, len = str.length();
 		for (; i < len; i++) //in case of start cof sign
 		{
@@ -391,7 +418,7 @@ else if ((ch | ' ') == '}')
 				{
 					String s = sbs[lastType].toString().trim();
 					if (!s.isEmpty())
-						ret[lastType].add(s);
+						ret[lastType].add(lastType == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s);
 					sbs[lastType] = new StringBuilder();
 				}
 				else
@@ -405,7 +432,7 @@ else if ((ch | ' ') == '}')
 		{
 			String s = sbs[type].toString().trim();
 			if (!s.isEmpty())
-				ret[type].add(s);
+				ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s);
 		}
 		return ret;
 	}
@@ -467,6 +494,8 @@ public static Object toNum(Object obj)
 	}
 	
 	/**
+	 * @deprecated THIS WAS QUIET A MESSY WORKAROUND, DO NOT USE!
+ * * Used internally by {@link ArithmeticOperators} to wrap result of evaluation! * Mainly used by String results! * @@ -474,6 +503,7 @@ public static Object toNum(Object obj) * * @since 1.3.0 */ + @Deprecated protected static class ResultWrapper { public final Object obj; From dce815db698594d50b8fede7592bb1136d9b26e0 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 9 Jul 2024 23:47:29 +0200 Subject: [PATCH 30/75] finally finsihing refactor of operators AritOprs and LogiOpers, reverting mistake with debug try catch, optimizing some stuff... --- .../src/main/java/org/ugp/serialx/Utils.java | 49 ++-- .../serialx/converters/NumberConverter.java | 2 +- .../serialx/devtools/DebugParserRegistry.java | 32 +-- .../org/ugp/serialx/juss/JussSerializer.java | 24 +- .../operators/ArithmeticOperators.java | 233 +++++++++--------- .../operators/ComparisonOperators.java | 2 +- .../operators/LogicalOperators.java | 94 ++++--- 7 files changed, 225 insertions(+), 211 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 43dd25c..f7eae53 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -596,13 +596,14 @@ else if (quote % 2 != 0) */ public static int indexOfNotInObj(CharSequence s, char... oneOf) { - return indexOfNotInObj(s, 0, s.length(), true, oneOf); + return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); } /** * @param s | CharSequence to search! * @param from | The beginning index, where to start the search (should be 0 in most cases). * @param to | Ending index of search (exclusive, should be s.length()). + * @param defaultReturn | Index to return by default (usually -1). * @param firstIndex | If true, first index will be returned, if false last index will be returned. * @param oneOf | Characters to find! * @@ -610,9 +611,8 @@ public static int indexOfNotInObj(CharSequence s, char... oneOf) * * @since 1.3.5 */ - public static int indexOfNotInObj(CharSequence s, int from, int to, boolean firstIndex, char... oneOf) + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) { - int index = -1; for (int brackets = 0, quote = 0; from < to; from++) { char ch = s.charAt(from); @@ -625,7 +625,7 @@ public static int indexOfNotInObj(CharSequence s, int from, int to, boolean firs { if (firstIndex) return from; - index = from; + defaultReturn = from; } else if ((ch | ' ') == '{') brackets++; @@ -638,7 +638,7 @@ else if ((ch | ' ') == '}') } } } - return index; + return defaultReturn; } /** @@ -714,23 +714,24 @@ else if ((ch | ' ') == '}') */ public static String fastReplace(String str, String target, CharSequence replacement) { - int targetLength = target.length(); - if (targetLength == 0) - return str; - - int i1 = 0, i2 = str.indexOf(target); - if (i2 < 0) - return str; - - StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? str.length() : str.length() * 2); - do - { - sb.append(str, i1, i2).append(replacement); - i1 = i2 + targetLength; - i2 = str.indexOf(target, i1); - } while (i2 > 0); - - return sb.append(str, i1, str.length()).toString(); + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + int len = str.length(); + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, len).toString(); } /** @@ -797,14 +798,14 @@ public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOt * @param str | String to display! * @param pos | Position to display! * - * @return String with displayed position! + * @return String with displayed position by using »! * Use for debugging or error printing! * * @since 1.3.2 */ public static String showPosInString(CharSequence str, int pos) { - return str + "\n" + multilpy(' ', pos) + "^"; + return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); } /* Arrays */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 10631eb..4ce0ae8 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -165,7 +165,7 @@ public String format(Number num) /** * @param str | Source char sequence with number to parse. * @param ch0 | Should be str.charAt(0). This is to ensure that string is not null or empty and also for possible optimizations. - * @param end | Index of where to end with parsing. If whole string is meant to be parsed, then str.length()-1, should not be greater than that! + * @param end | Index of where to end with parsing (inclusive). If whole string is meant to be parsed, then str.length()-1, should not be greater than that! * @param base | Base of the parsed number. Theoretically can be anything but usually should be 2, 8, 10 or 16... Note that base will be overridden by suffixes #. for 16, 0x for 16, 0b for 2 or 0 for 8 (only if not followed by .). * @param type | Preferred datatype of of the number represented by suffixes 'S' for {@link Short}, 'Y' for {@link Byte}, 'L' for {@link Long}, 'D' for {@link Double}, 'F' for {@link Float}. Other stands for {@link Integer}.
* Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!
diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index 5d5cc77..bc7e8e0 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -114,8 +114,8 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); return obj; } - } - catch (Exception ex) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " (from cache)\n>>\t\"" + str + "\"\tthrew\t" + ex); - return null; - } +// } +// catch (Exception ex) +// { +// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " (from cache)\n>>\t\"" + str + "\"\tthrew\t" + ex); +// return null; +// } } } @@ -139,8 +139,8 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); return obj; } - } - catch (Exception ex) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + "\n>>\t\"" + str + "\"\tthrew\t" + ex); - return null; - } +// } +// catch (Exception ex) +// { +// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + "\n>>\t\"" + str + "\"\tthrew\t" + ex); +// return null; +// } } if (returnAsStringIfNotFound) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 57a19f9..939f75e 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -408,8 +408,8 @@ public S LoadFrom(Reader reader, Object... args) if (args[3] == null) args[3] = getProtocols(); - String str = readAndFormat(reader, formatRequired); - List objs = splitAndParse(str, 0, args); + StringBuilder str = readAndFormat(reader, formatRequired); + List objs = splitAndParse(str, args); addAll(objs); //double t0 = System.nanoTime(); @@ -504,7 +504,7 @@ else if (ch == '}' || ch == ']') * * @since 1.3.2 */ - protected String readAndFormat(Reader reader, boolean format) + protected StringBuilder readAndFormat(Reader reader, boolean format) { int quote = 0, multLineCom = -1; //int brackets = 0, lastIndex = 0, delChars = 0; @@ -581,7 +581,7 @@ else if (ch == '}' || ch == ']') e.printStackTrace(); } - return sb.toString(); + return sb; } /** @@ -589,16 +589,16 @@ else if (ch == '}' || ch == ']') * * @since 1.3.2 */ - protected List splitAndParse(String formattedStr, int offset, Object... parserArgs) + protected List splitAndParse(StringBuilder formattedStr, Object... parserArgs) { List result = new ArrayList<>(); ParserRegistry reg = getParsers(); //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; - int brackets = 0, quote = 0, lastIndex = 0; + int brackets = 0, quote = 0, lastIndex = 0, len = formattedStr.length(); //boolean isBracketSplit = false; - for (int i = 0, len = formattedStr.length(); i < len; i++) + for (int i = 0; i < len; i++) { char ch = formattedStr.charAt(i); if (ch == '"') @@ -611,8 +611,8 @@ protected List splitAndParse(String formattedStr, int offset, Object... isBracketSplit = false;*/ if (brackets == 0 && (ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) { - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/); - if (!(str = str.trim()).isEmpty()) + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); + if (!str.isEmpty()) { Object obj = parseObject(reg, str, parserArgs); if (obj != VOID) @@ -638,8 +638,8 @@ else if (brackets > 0) throw new IllegalArgumentException("Unclosed brackets in: " + formattedStr); else { - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, formattedStr.length()); - if (!(str = str.trim()).isEmpty()) + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); + if (!str.isEmpty()) { Object obj = parseObject(reg, str, parserArgs); if (obj != VOID) @@ -704,7 +704,7 @@ public T cloneOf(String variableName) */ public T cloneOf(String variableName, T defaultValue) { - T obj = get(variableName , defaultValue); + T obj = get(variableName, defaultValue); if (obj == defaultValue) return defaultValue; return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index b3cc5fd..91b4a9d 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -1,11 +1,7 @@ package org.ugp.serialx.converters.operators; import static java.util.Arrays.asList; -import static org.ugp.serialx.Utils.fastReplace; -import static org.ugp.serialx.Utils.fromAmbiguousArray; -import static org.ugp.serialx.Utils.isOneOf; -import static org.ugp.serialx.Utils.mergeArrays; -import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.Utils.*; import java.util.ArrayList; import java.util.Collection; @@ -26,96 +22,108 @@ */ public class ArithmeticOperators implements DataParser { -// protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"}; - - @Override - public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) - { - if (s.length() > 2 && isExpression(s, '+', '-', '*', '/', '%')) - return eval(myHomeRegistry, s, args); - return CONTINUE; - } + /** + * @deprecated DO NOT USE! USE {@link ArithmeticOperators#evalOperator(Object, String, Object)} AND {@link ArithmeticOperators#getOperatorPriority(String)} INSTEAD! + */ + @Deprecated + protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"}; /** - * @return Result of evaluated expression that was inserted! For instance 5 + 5, result 10! + * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator(Object, String, Object)}.
Intended for override, should not be null or empty! * - * @since 1.3.0 + * @since 1.3.7 */ + protected char[] operators = {'+', '-', '*', '/', '%'}; + @SuppressWarnings("unchecked") - protected Object eval(ParserRegistry registryForParsers, String expr, Object... argsForParsers) + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - while (expr.contains("++") || expr.contains("--") || expr.contains("+-") || expr.contains("-+")) - expr = fastReplace(fastReplace(fastReplace(fastReplace(expr, "-+", "-"), "+-", "-"), "--", "+"), "++", "+"); + int len; + if ((len = str.length()) > 2 && isExpression(str, len, operators)) + { + for (int i; (i = indexOfNotInObj(str, 0, len, len, true, '+', '-')+1) < len && isOneOf(str.charAt(i), '+', '-'); ) // Handle duplicates of [+-]{2} + str = fastReplace(fastReplace(fastReplace(fastReplace(str, "-+", "-"), "+-", "-"), "--", "+"), "++", "+"); - List[] terms = getAndParseTerms(expr, registryForParsers, argsForParsers, getClass(), '+', '-', '*', '/', '%'); - ArrayList cofs = (ArrayList) terms[0]; - if (cofs.size() <= 1) - return cofs.get(0); - LinkedList oprs = (LinkedList) terms[1]; + List[] terms = getAndParseTerms(str, myHomeRegistry, args, getClass(), operators); + ArrayList cofs = (ArrayList) terms[0]; + if (cofs.size() <= 1) + return cofs.get(0); + LinkedList oprs = (LinkedList) terms[1]; - Object cof1 = null, cof2 = null; - String opr = null; - try - { - for (int i = 0, index = 0, oprsSize = oprs.size(), currentOpPrio = 2; i < oprsSize; index = 0, i++) + String op = null; + int index = 1; + try { - opPrioCheck: //Yes yes... this is quite a shenanigan but it is fast... - { - for (; currentOpPrio > 0; currentOpPrio--) + for (int opPrio = 2; opPrio > 0; opPrio--) + for (ListIterator iter = oprs.listIterator(); iter.hasNext(); ) { - for (ListIterator iter = oprs.listIterator(); iter.hasNext();) + if (getOperatorPriority(op = iter.next()) == opPrio) { - if (getOperatorPriority(opr = iter.next()) == currentOpPrio) - { - iter.remove(); - index = iter.nextIndex(); - break opPrioCheck; - } + iter.remove(); + cofs.set(index = iter.nextIndex(), operator(cofs.get(index), op, cofs.remove(index + 1))); } - opr = null; } - opr = oprs.poll(); //opr = null; - } - - cof1 = cofs.get(index); - cof2 = cofs.remove(index + 1); - - switch (opr.charAt(0)) - { - case '+': - cofs.set(index, addOperator(cof1, cof2)); break; - case '-': - cofs.set(index, subOperator(cof1, cof2)); break; - case '*': - if (opr.length() > 1 && opr.charAt(1) == '*') - { - cofs.set(index, powOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break; - } - cofs.set(index, multOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break; - case '/': - cofs.set(index, divOperator(cof1, cof2, opr.endsWith("-") ? -1 : 1)); break; - case '%': - cofs.set(index, modOperator(cof1, cof2)); break; - } + + for (index = 1; (op = oprs.poll()) != null; ) + cofs.set(0, operator(cofs.get(0), op, cofs.get(index++))); } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Arithmetic operator " + op + " is undefined between provided operands because " + ex.getMessage() + "!", ex); + } + catch (IndexOutOfBoundsException ex) + { + LogProvider.instance.logErr("Missing operand in \"" + str + "\"!", null); + } + catch (ArithmeticException ex) + { + LogProvider.instance.logErr(ex.getMessage(), ex); + } + + return cofs.get(0); } - catch (ClassCastException ex) - { - LogProvider.instance.logErr("Arithmetic operator " + opr + " is undefined between " + cof1.getClass().getName() + " and " + cof2.getClass().getName() + "!", ex); - } - catch (IndexOutOfBoundsException ex) - { - LogProvider.instance.logErr("Missing coefficient in \"" + expr + "\"!", null); - } - catch (ArithmeticException ex) + return CONTINUE; + } + + /** + * @param opr1 | Operand 1 + * @param op | The operator/operation + * @param opr2 | Operand 2 + * + * @return Result of binary operation described by op between opr1 and opr2! If operator is not known, opr1 will be returned by default! + * + * @since 1.3.7 + */ + public Object operator(Object opr1, String op, Object opr2) + { +// System.err.println(opr1 + op + opr2); + switch (op.charAt(0)) { - LogProvider.instance.logErr(ex.getMessage(), ex); + case '+': + return addOperator(opr1, opr2); + case '-': + return subOperator(opr1, opr2); + case '*': + if (op.length() > 1 && op.charAt(1) == '*') + return powOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + return multOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + case '/': + return divOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + case '%': + return modOperator(opr1, opr2); } - - return cofs.get(0); + return opr1; } - public int getOperatorPriority(String op) + /** + * @param op | The operator/operation + * + * @return Priority of provided operator (higher number = higher priority, 2 = high, 1 = medium, 0 = low) + * + * @since 1.3.7 + */ + public byte getOperatorPriority(String op) { switch (op.charAt(0)) { @@ -360,28 +368,27 @@ public static Object mod(Object cof, Object cof2) */ public static Object pow(Object cof, Object cof2, int sign) { - if (cof instanceof Number && cof2 instanceof Number) - { - double pow = Math.pow(((Number) cof).doubleValue(), ((Number) cof2).doubleValue() * sign); - if (pow > Long.MAX_VALUE || pow < Long.MIN_VALUE || cof instanceof Double || cof2 instanceof Double) - return pow; - else if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Float || cof2 instanceof Float)) - return (float) pow; - - if (pow > Integer.MAX_VALUE || pow < Integer.MIN_VALUE || cof instanceof Long || cof2 instanceof Long) - return (long) pow; - else if (cof instanceof Integer || cof2 instanceof Integer) - return (int) pow; - } - return null; + double pow = Math.pow(((Number) cof).doubleValue(), ((Number) cof2).doubleValue() * sign); + if (pow > Long.MAX_VALUE || pow < Long.MIN_VALUE || cof instanceof Double || cof2 instanceof Double) + return pow; + if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Float || cof2 instanceof Float)) + return (float) pow; + + if (pow > Integer.MAX_VALUE || pow < Integer.MIN_VALUE || cof instanceof Long || cof2 instanceof Long) + return (long) pow; + if (cof instanceof Integer || cof2 instanceof Integer) + return (int) pow; + return pow; } - + /** - * * @param str | String to split! - * @param oprs | Operators to use as a splitters. + * @param registryForParsers | Registry to use for parsing operands! + * @param argsForParsers | Arguments for the parse method! + * @param classToIgnore | Parser to ignore (should be class of the caller if possible)! + * @param oprs | Operators to use as a splitters. 1 or more of these in row will be used as delimiter! * - * @return List of terms splitted according to inserted arguments! For example getTerm("5 + 6", true, '+') will return [+], while getTerm("5 + 6", false, '+') will return [5, 6]! + * @return Array with 2 lists. Index 0 is {@link ArrayList} containing parsed operands of the expression, index 1 is {@link LinkedList} containing operators of the expression! * * @since 1.3.7 (originally getTerms since 1.3.0) */ @@ -390,17 +397,8 @@ public static List[] getAndParseTerms(String str, ParserRegistry registryForP { List[] ret = new List[] {new ArrayList(), new LinkedList()}; //cofs, ops - StringBuilder[] sbs = {new StringBuilder(), new StringBuilder()}; //cofs, ops TODO - - int i = 0, type = 0, len = str.length(); - for (; i < len; i++) //in case of start cof sign - { - char ch = str.charAt(i); - if (isOneOf(ch, oprs)) - sbs[0].append(ch); - else - break; - } + int i = 0, startIndex = 0, type = 0, len = str.length(); + for (; i < len && isOneOf(str.charAt(i), oprs); i++); //in case of start cof sign for (int quote = 0, brackets = 0, lastType = type; i < len; i++) { @@ -416,39 +414,38 @@ else if ((ch | ' ') == '}') { if ((type = isOneOf(ch, oprs) ? 1 : 0) != lastType) { - String s = sbs[lastType].toString().trim(); + String s = str.substring(startIndex, i).trim(); if (!s.isEmpty()) ret[lastType].add(lastType == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); - sbs[lastType] = new StringBuilder(); + startIndex = i; } else type = lastType; } - - sbs[lastType = type].append(ch); - } - - if (sbs[type].length() > 0) - { - String s = sbs[type].toString().trim(); - if (!s.isEmpty()) - ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); + + lastType = type; } + + String s = str.substring(startIndex, len).trim(); + if (!s.isEmpty()) + ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); +// System.err.println(ret[0] + "\n" + ret[1] + "\n"); return ret; } /** * @param str | String that might be an expression! + * @param to | Ending index of checking, exclusive (should be str.length())! * @param operators | Operators that str must have! * * @return True if inserted string is expression with any coefficients splitted by operators! * * @since 1.3.2 */ - public static boolean isExpression(CharSequence str, char... operators) + public static boolean isExpression(CharSequence str, int to, char... operators) { int hasOpr = -1; - for (int i = 0, len = str.length(), oldCh = 0, isCof = 0, quote = 0, brackets = 0; i < len; i++) + for (int i = 0, oldCh = 0, isCof = 0, quote = 0, brackets = 0; i < to; i++) { char ch = str.charAt(i); if (ch > 32) diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index b60d778..39a34d7 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -29,7 +29,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) return CONTINUE; int index, op; - if ((index = indexOfNotInObj(str, '<', '>', '=')) > -1) + if ((index = indexOfNotInObj(str, 0, len, -1, true, '<', '>', '=')) > -1) { if ((op = str.charAt(index)) != '=') // > < { diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index 5e60f17..be0cbcd 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -3,7 +3,9 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.multilpy; +import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; /** @@ -16,47 +18,59 @@ public class LogicalOperators implements DataParser { @Override - public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) { int len; if ((len = s.length()) < 3) return CONTINUE; Object result = CONTINUE; - int i = 0, index; - do + int i = 0, index, op = 0, nextOpIndex; + try { - if ((index = indexOfNotInObj(s, i, len, true, '&', '|', '^')) == -1) - return result; - - int op; - if ((op = s.charAt(i = index)) != '^' && (++i >= len || s.charAt(i) != op)) // Ensure && and || and refuse & and | - continue; - - if (result == CONTINUE) // Beginning - result = myHomeRegistry.parse(s.substring(0, index).trim(), args); - - int nextOpIndex; - if ((nextOpIndex = indexOfNotInObj(s, ++i, len, true, '&', '|', '^')) == -1) - nextOpIndex = len; - - if (op == '&') + do { - if (!FALSE.equals(result)) + if ((index = indexOfNotInObj(s, i, len, -1, true, '&', '|', '^')) == -1) + return result; //CONTINUE; + if ((op = s.charAt(i = index)) != '^' && (++i >= len || s.charAt(i) != op)) // Ensure && and || and refuse & and | + continue; + + if (result == CONTINUE) // Beginning + result = myHomeRegistry.parse(s.substring(0, index).trim(), args); + + if (op == '|') + { + if (TRUE.equals(result)) + return TRUE; + + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); + result = orOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + else if (op == '&') + { + if (FALSE.equals(result)) + { + i = indexOfNotInObj(s, ++i, len, len, true, '|', '^'); + continue; + } + + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); result = andOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + else + { + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); + result = xorOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + + i = nextOpIndex; } - else if (op == '|') - { - if (TRUE.equals(result)) - return TRUE; - result = orOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); - } - else - result = xorOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); - - i = nextOpIndex; + while (i < len); + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Logical operator " + multilpy((char) op, op != '^' ? 2 : 1) + " is undefined between provided operands because " + ex.getMessage() + "!", ex); } - while (i < len); return result; } @@ -99,19 +113,21 @@ public Object xorOperator(Object obj1, Object obj2) public static Object toBool(Object obj) { if (obj == null) - return false; + return FALSE; if (obj instanceof Number) return ((Number) obj).doubleValue() != 0; if (obj instanceof Character) return (char) obj != 0; - /*if (obj instanceof Map) - return !((Map) obj).isEmpty(); - if (obj instanceof Collection) - return !((Collection) obj).isEmpty(); - if (obj instanceof Scope) - return !((Scope) obj).isEmpty(); - if (obj.getClass().isArray()) - return Array.getLength(obj) > 0;*/ +// if (obj instanceof CharSequence) +// return ((CharSequence) obj).length() > 0; +// if (obj instanceof Map) +// return !((Map) obj).isEmpty(); +// if (obj instanceof Collection) +// return !((Collection) obj).isEmpty(); +// if (obj instanceof Scope) +// return !((Scope) obj).isEmpty(); +// if (obj.getClass().isArray()) +// return Array.getLength(obj) > 0; return obj; } } \ No newline at end of file From bea917d93261385ad2a43e6df85aee79126303b6 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 12 Jul 2024 21:59:42 +0200 Subject: [PATCH 31/75] fixing bugs and doing small optim --- .../java/org/ugp/serialx/GenericScope.java | 4 ++-- .../main/java/org/ugp/serialx/Serializer.java | 10 +++++++++ .../ugp/serialx/converters/DataParser.java | 2 +- .../serialx/converters/NumberConverter.java | 4 ++-- .../juss/converters/VariableConverter.java | 2 +- .../operators/ArithmeticOperators.java | 21 ++++++++++++------- .../operators/NegationOperator.java | 17 +++++++-------- 7 files changed, 37 insertions(+), 23 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 359e51d..7f0fb21 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -1024,7 +1024,7 @@ public static GenericScope newBidirectional(Map variablesMap, * * @since 1.3.5 */ - public static GenericScope intoBidirectional(GenericScope scopeToMakeBidirectional, Map variablesMap, List values) + public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values) { return intoBidirectional(scopeToMakeBidirectional, variablesMap, values, null); } @@ -1039,7 +1039,7 @@ public static GenericScope intoBidirectional(GenericScope sco * * @since 1.3.5 */ - public static GenericScope intoBidirectional(GenericScope scopeToMakeBidirectional, Map variablesMap, List values, GenericScope parent) + public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values, GenericScope parent) { scopeToMakeBidirectional.variables = variablesMap; scopeToMakeBidirectional.values = values; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 8b0fc6b..a5bc254 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -164,6 +164,16 @@ public T toObject(Class objClass) throws Exception return toObject(objClass, getProtocols()); } + @SuppressWarnings("unchecked") + @Override + public GenericScope transform(Function trans, boolean includeSubScopes) + { + Serializer transformed = (Serializer) super.transform(trans, includeSubScopes); + transformed.parsers = getParsers(); + transformed.protocols = getProtocols(); + return (GenericScope) transformed; + } + /** * @see Serializer#into(Object, Serializer, String...) */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index e55a673..59a1be7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -45,7 +45,7 @@ public interface DataParser /** * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! - * @param str | Source string! + * @param str | Source string, preferably trimed! * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! * * @return Object that was parsed from obtained string. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 4ce0ae8..e873476 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -112,8 +112,8 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) int len; if ((len = arg.length()) > 0) { - char ch0 = arg.charAt(0); - if (ch0 == '+' || ch0 == '-' || ch0 == '.' || (ch0 >= '0' && ch0 <= '9')) + char ch0; + if ((ch0 = arg.charAt(0)) >= '0' && ch0 <= '9' || (ch0 == '+' || ch0 == '-' || ch0 == '.') && len > 1 && arg.charAt(1) > '*') { Number num; if ((num = numberOf(arg, ch0, --len, 10, 0)) != null) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 7e0038c..9d281e1 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -69,7 +69,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) op0Index--; } - String vars[] = splitValues(arg, op0Index, 0, 1, new char[] {'?'}, '=', ':'), valStr; + String vars[] = splitValues(arg, op0Index, 0, 1, new char[] {'?', '<', '>', '!'}, '=', ':'), valStr; Object val = null; int iVal = vars.length-1; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 91b4a9d..62f7bf7 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -42,10 +42,14 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) int len; if ((len = str.length()) > 2 && isExpression(str, len, operators)) { - for (int i; (i = indexOfNotInObj(str, 0, len, len, true, '+', '-')+1) < len && isOneOf(str.charAt(i), '+', '-'); ) // Handle duplicates of [+-]{2} - str = fastReplace(fastReplace(fastReplace(fastReplace(str, "-+", "-"), "+-", "-"), "--", "+"), "++", "+"); + for (int i = 0; i < len; ) // Format duplicates of [+-]{2} + if (isOneOf(str.charAt(i++), '+', '-') && i < len && isOneOf(str.charAt(i), '+', '-')) + { + len = (str = fastReplace(fastReplace(fastReplace(fastReplace(str, "-+", "-"), "+-", "-"), "--", "+"), "++", "+")).length(); + i--; + } - List[] terms = getAndParseTerms(str, myHomeRegistry, args, getClass(), operators); + List[] terms = getAndParseTerms(str, len, myHomeRegistry, args, getClass(), operators); ArrayList cofs = (ArrayList) terms[0]; if (cofs.size() <= 1) return cofs.get(0); @@ -383,6 +387,7 @@ public static Object pow(Object cof, Object cof2, int sign) /** * @param str | String to split! + * @param to | Ending index of parsing, exclusive. Everything from this index to the end will be ignored (should be str.length())! * @param registryForParsers | Registry to use for parsing operands! * @param argsForParsers | Arguments for the parse method! * @param classToIgnore | Parser to ignore (should be class of the caller if possible)! @@ -393,14 +398,14 @@ public static Object pow(Object cof, Object cof2, int sign) * @since 1.3.7 (originally getTerms since 1.3.0) */ @SuppressWarnings("unchecked") - public static List[] getAndParseTerms(String str, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs) + public static List[] getAndParseTerms(String str, int to, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs) { List[] ret = new List[] {new ArrayList(), new LinkedList()}; //cofs, ops - int i = 0, startIndex = 0, type = 0, len = str.length(); - for (; i < len && isOneOf(str.charAt(i), oprs); i++); //in case of start cof sign + int i = 0, startIndex = 0, type = 0; + for (; i < to && isOneOf(str.charAt(i), oprs); i++); //in case of start cof sign - for (int quote = 0, brackets = 0, lastType = type; i < len; i++) + for (int quote = 0, brackets = 0, lastType = type; i < to; i++) { char ch = str.charAt(i); if (ch == '\"') @@ -426,7 +431,7 @@ else if ((ch | ' ') == '}') lastType = type; } - String s = str.substring(startIndex, len).trim(); + String s = str.substring(startIndex, to).trim(); if (!s.isEmpty()) ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); // System.err.println(ret[0] + "\n" + ret[1] + "\n"); diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java index f644357..99f6702 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -16,20 +16,19 @@ public class NegationOperator implements DataParser @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - int ch, len = str.length(); - if (len > 0 && ((ch = str.charAt(0)) == '!' || ch == '-')) + int len, type; + if ((len = str.length()) < 2) + return CONTINUE; + if ((type = str.charAt(0)) == '!' || type == '-') { int negCount = 1; - for (int i = negCount; i < len; i++) - if ((ch = str.charAt(i)) == '!' || ch == '-') - negCount++; - else - break; + for (int ch; negCount < len && ((ch = str.charAt(negCount)) == '!' || ch == '-'); negCount++); - Object obj = myHomeRegistry.parse(str.substring(negCount), args); + Object obj = myHomeRegistry.parse(str.substring(negCount).trim(), false, getClass(), args); if (negCount % 2 == 0) return obj; - Object neg = ch == '!' ? logicalNotOperator(obj) : notOperator(obj); + + Object neg = type == '!' ? logicalNotOperator(obj) : notOperator(obj); if (obj == neg && !(obj instanceof Number && ((Number) obj).intValue() == 0)) LogProvider.instance.logErr("Unable to nagete \"" + obj + "\" because object of \"" + obj.getClass().getName() + "\" cant be negated!", null); return neg; From a644ba6c7a6a2dbc26eff5f673ae62b67276baac Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 19 Jul 2024 22:21:30 +0200 Subject: [PATCH 32/75] fixing some Json related bugs, small refactoring, intoNew can now handle generics in some cases, and AutoProt and UniversalProt/SelfSerial can too. This greatly increases the Json capabilities. --- .../java/org/ugp/serialx/GenericScope.java | 127 +++--- .../src/main/java/org/ugp/serialx/Scope.java | 374 ++++++++++++------ .../main/java/org/ugp/serialx/Serializer.java | 12 +- .../ugp/serialx/converters/DataParser.java | 2 +- .../org/ugp/serialx/json/JsonSerializer.java | 2 + .../json/converters/JsonObjectConverter.java | 15 +- .../serialx/juss/protocols/AutoProtocol.java | 60 +-- .../UniversalObjectInstantiationProtocol.java | 41 +- 8 files changed, 429 insertions(+), 204 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 7f0fb21..49aa640 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -3,6 +3,7 @@ import static org.ugp.serialx.Utils.Instantiate; import java.io.Serializable; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -273,8 +274,8 @@ public V get(KeyT variableKey) @SuppressWarnings("unchecked") public V get(KeyT variableKey, V defaultValue) { - V obj = (V) variables().get(variableKey); - if (obj == null) + V obj; + if ((obj = (V) variables().get(variableKey)) == null) return defaultValue; return obj; } @@ -342,7 +343,7 @@ public V get(KeyT... pathToValue) * * @since 1.3.7 */ - public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception + public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception { V obj = get(variableKey, defaultValue); if (obj != null && obj.getClass() == cls) @@ -477,7 +478,7 @@ public boolean addAll(@SuppressWarnings("unchecked") ValT... values) * @since 1.3.7 */ @Override - public boolean containsAll(Collection values) + public boolean containsAll(Collection values) { return values().containsAll(values); } @@ -550,36 +551,41 @@ public GenericScope getGenericScope(K... pathToScope) } /** - * @param objClass | Object of class to create. + * @param type | Class of object to create (may or may not support other implementations of {@link Type}). * - * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! * * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! * * @since 1.2.5 */ - public T toObject(Class objClass) throws Exception + public T toObject(Type type) throws Exception { - return toObject(objClass, SerializationProtocol.REGISTRY); + return toObject(type, SerializationProtocol.REGISTRY); } /** - * @param objClass | Object of class to create using protocols. + * @param type | Class of object to create using protocols (may or may not support other implementations of {@link Type}). * @param protocolsToUse | Registry of protocols to use. * - * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * @return Object of class constructed from this scopes independent values using protocol for given class or null if there was no protocol found in protocolsToUse! * * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! * * @since 1.3.2 */ - public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception + @SuppressWarnings("unchecked") + public T toObject(Type type, ProtocolRegistry protocolsToUse) throws Exception { - SerializationProtocol pro = protocolsToUse == null ? null : protocolsToUse.GetProtocolFor(objClass, SerializationProtocol.MODE_DESERIALIZE); - if (pro != null) + if (protocolsToUse == null) + return null; + + Class objClass; + SerializationProtocol pro; + if ((pro = protocolsToUse.GetProtocolFor(objClass = (Class) type, SerializationProtocol.MODE_DESERIALIZE)) != null) { - T obj = pro.unserialize(objClass, this.variablesCount() > 0 ? new Object[] {this} : this.toArray()); - if (obj != null) + T obj; + if ((obj = pro.unserialize(objClass, variablesCount() > 0 ? new Object[] {this} : toArray())) != null) return obj; } return null; @@ -588,7 +594,7 @@ public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws /** * @param predicate | Predicate object with filter condition in test method! * - * @return Original scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! * * @since 1.2.5 */ @@ -603,14 +609,14 @@ public GenericScope filter(Predicate predicate) * If sub-scope is empty after filtration it will not be included in result! * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! * - * @return Original scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! + * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! * * @since 1.2.5 */ @SuppressWarnings("unchecked") public GenericScope filter(Predicate predicate, boolean includeSubScopes) { - return (GenericScope) transform(new Function() + return (GenericScope) transform(new Function() { @Override public Object apply(ValT t) @@ -623,7 +629,7 @@ public Object apply(ValT t) /** * @param trans | Function to transform objects of this scope! * - * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! * * @since 1.2.5 */ @@ -638,7 +644,7 @@ public GenericScope transform(Function trans) * If sub-scope is empty after transformation it will not be included in result! * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! * - * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! * * @since 1.2.5 */ @@ -648,41 +654,40 @@ public GenericScope transform(Function trans, boolean incl if (trans == null || isEmpty()) return (GenericScope) this; - List fltVals = map(trans, includeSubScopes); - LinkedHashMap fltVars = new LinkedHashMap<>(); - + LinkedHashMap mappedVars = new LinkedHashMap<>(); for (Entry ent : this.varEntrySet()) try { Object obj = ent.getValue(); - if (obj instanceof GenericScope && includeSubScopes) + if (includeSubScopes && obj instanceof GenericScope) { GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); if (!sc.isEmpty()) - fltVars.put(ent.getKey(), (V) sc); + mappedVars.put(ent.getKey(), (V) sc); } else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) - fltVars.put(ent.getKey(), trans.apply((ValT) obj)); + mappedVars.put(ent.getKey(), trans.apply((ValT) obj)); } catch (ClassCastException e) {} - try + List mappedVals = map(trans, includeSubScopes); + try { GenericScope clone = Instantiate(getClass()); - clone.values = fltVals; - clone.variables = fltVars; + clone.values = mappedVals; + clone.variables = mappedVars; clone.parent = getParent(); return clone; } catch (Exception e) { - return new GenericScope<>(fltVars, fltVals, getParent()); + return new GenericScope<>(mappedVars, mappedVals, getParent()); } } /** - * @param trans | Function to transform objects of this scope! + * @param trans | Function to transform independent objects of this scope! * * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! * @@ -694,7 +699,7 @@ public List map(Function trans) } /** - * @param trans | Function to transform objects of this scope! + * @param trans | Function to transform independent objects of this scope! * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). * If sub-scope is empty after transformation it will not be included in result! * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! @@ -706,23 +711,50 @@ public List map(Function trans) @SuppressWarnings("unchecked") public List map(Function trans, boolean includeSubScopes) { - List fltVals = new ArrayList<>(); - for (Object obj : this) +// List mapped = new ArrayList<>(size()); +// for (Object obj : this) +// try +// { +// if (obj instanceof GenericScope && includeSubScopes) +// { +// GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); +// if (!sc.isEmpty()) +// mapped.add((V) sc); +// } +// else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) +// mapped.add((V) obj); +// } +// catch (ClassCastException e) +// {} + + List mapped = (List) toValList(); + for (int i = valuesCount()-1; i >= 0; i--) + { try { - if (obj instanceof GenericScope && includeSubScopes) + Object obj = mapped.get(i); + if (includeSubScopes && obj instanceof GenericScope) { - GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); + GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); if (!sc.isEmpty()) - fltVals.add((V) sc); + { + mapped.set(i, (V) sc); + continue; + } } else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) - fltVals.add((V) obj); + { + mapped.set(i, (V) obj); + continue; + } } - catch (ClassCastException e) + catch (ClassCastException e) {} + + mapped.remove(i); + } - return fltVals; + return mapped; } /** @@ -857,13 +889,14 @@ public boolean isEmpty() } /** - * @return The parent scope of this scope or null if this scope has no parent such as default one in file. + * @return The parent scope of this scope or null if this scope has no parent such as default one in file.
+ * Note: This may or may not be always null based on the way this scope was instantiated... * * @since 1.2.0 */ public > T getParent() { - return getParent(1); + return getParent(1); } /** @@ -871,7 +904,8 @@ public boolean isEmpty() * If you want to get the root parent (the one that has no parent), simply put a big number as depth. 99 should be enough! * * @return The parent scope based on depth or null if this scope has no parent which means its already root (default one in file). - * If depth was bigger than 1, null will be never returned, last not null parent will be returned instead!
+ * If depth was bigger than 1, null will not be returned, last not null parent will be returned instead!
+ * Note: This may or may not be always null based on the way this scope was instantiated... * * @since 1.3.2 */ @@ -888,7 +922,7 @@ public boolean isEmpty() } /** - * @return New {@link LinkedHashMap} with variables of this a in defined order! Key is a KeyT of variable and value is its value!
+ * @return New {@link LinkedHashMap} with variables of this a in defined order! Key is a KeyT of variable and value is its value!
* Modifying this map will not affect this GenericScope object! * * @since 1.2.0 @@ -900,7 +934,8 @@ public boolean isEmpty() /** * @return New {@link ArrayList} with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! - * Modifying this list will not affect this GenericScope object! + * Modifying this list will not affect this GenericScope object!
+ * Note: Returning other {@link List} implementations than {@link ArrayList} (or other collection that stores elements in "array-like fashion") may result in serious performance implications! Queues or LinkedLists are the prime examples to avoid! * * @since 1.2.0 */ @@ -1056,7 +1091,7 @@ public static > S intoBidirectional(S scopeTo * @since 1.3.7 */ @SuppressWarnings("unchecked") - public static Map mapKvArray(Map map, Object... kVkVkV) + public static > M mapKvArray(M map, Object... kVkVkV) { for (int i = 1; i < kVkVkV.length; i+=2) map.put((K) kVkVkV[i-1], (V) kVkVkV[i]); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index ca80662..a7a9fc0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1,17 +1,22 @@ package org.ugp.serialx; import static org.ugp.serialx.Utils.Instantiate; +import static org.ugp.serialx.Utils.equalsLowerCase; import static org.ugp.serialx.converters.DataParser.VOID; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.Array; import java.lang.reflect.Field; +import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; @@ -111,25 +116,28 @@ public Scope clone() } /** - * @param objClass | Object of class to create using protocols. + * @param objClass | Class of object to create using protocols. * @param protocolsToUse | Registry of protocols to use. * - * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in protocolsToUse! * If there were no suitable deserialization protocols found, {@link Scope#into(Class, String...)} will be used! * * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! * * @see Scope#into(Class, String...) - * @see Scope#intoNew(Class, GenericScope, String...) + * @see Scope#intoNew(Type, GenericScope, String...) * * @since 1.3.5 */ @Override - public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws Exception + public T toObject(Type objClass, ProtocolRegistry protocolsToUse) throws Exception { - T obj = super.toObject(objClass, protocolsToUse); - if (obj != null) - return obj; + if (objClass instanceof Class) + { + T obj; + if ((obj = super.toObject(objClass, protocolsToUse)) != null) + return obj; + } try { @@ -137,7 +145,7 @@ public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws } catch (Exception e) { - LogProvider.instance.logErr("Unable to create new instance of " + objClass.getName() + " because none of provided protocols were suitable and class introspection has failed as well!", e); + LogProvider.instance.logErr("Unable to create new instance of " + objClass + " because none of provided protocols were suitable and class introspection has failed as well!", e); return null; } } @@ -146,7 +154,9 @@ public T toObject(Class objClass, ProtocolRegistry protocolsToUse) throws * @param variableName | Variables name. * * @return Byte value of variable with name or 0 if there is no such a one! - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -160,7 +170,9 @@ public byte getByte(String variableName) * @param defaultValue | Default value to return. * * @return Byte value of variable with name or defaultValue if there is no such a one or given key contains null! - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -173,7 +185,9 @@ public byte getByte(String variableName, byte defaultValue) * @param variableName | Variables name. * * @return Byte value of variable with name or 0 if there is no such a one! - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -187,7 +201,9 @@ public short getShort(String variableName) * @param defaultValue | Default value to return. * * @return Byte value of variable with name or defaultValue if there is no such a one or given key contains null! - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -200,7 +216,9 @@ public short getShort(String variableName, short defaultValue) * @param variableName | Variables name. * * @return Int value of variable with name or 0 if there is no such a one! - * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Int will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -214,7 +232,9 @@ public int getInt(String variableName) * @param defaultValue | Default value to return. * * @return Int value of variable with name or defaultValue if there is no such a one or given key contains null! - * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Int will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -227,13 +247,15 @@ public int getInt(String variableName, int defaultValue) * @param variableName | Variables name. * * @return Long value of variable with name or 0 if there is no such a one! - * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Long will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ - public int getLong(String variableName) + public long getLong(String variableName) { - return getInt(variableName, 0); + return getLong(variableName, 0); } /** @@ -241,7 +263,9 @@ public int getLong(String variableName) * @param defaultValue | Default value to return. * * @return Long value of variable with name or defaultValue if there is no such a one or given key contains null! - * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Long will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -254,7 +278,9 @@ public long getLong(String variableName, long defaultValue) * @param variableName | Variables name. * * @return Float value of variable with name or 0 if there is no such a one! - * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Float will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -268,7 +294,9 @@ public float getFloat(String variableName) * @param defaultValue | Default value to return. * * @return Float value of variable with name or defaultValue if there is no such a one or given key contains null! - * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Float will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -281,7 +309,9 @@ public float getFloat(String variableName, float defaultValue) * @param variableName | Variables name. * * @return Double value of variable with name or 0 if there is no such a one! - * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Double will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -295,7 +325,9 @@ public double getDouble(String variableName) * @param defaultValue | Default value to return. * * @return Double value of variable with name or defaultValue if there is no such a one or given key contains null! - * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Double will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -304,18 +336,16 @@ public double getDouble(String variableName, double defaultValue) Object obj = get(variableName, defaultValue); if (obj instanceof Number) return ((Number) obj).doubleValue(); - else if (obj instanceof Character) + if (obj instanceof Character) return (double) (char) obj; - else if (obj instanceof CharSequence) - return Double.parseDouble(obj.toString()); - return (double) obj; + return Double.parseDouble(obj.toString()); } /** * @param variableName | Variables name. * * @return String value of variable with name or null if there is no such a one! - * String will be also parsed from any object using {@link Object#toString()}! + * String will be also obtained from any object using {@link String#valueOf(Object)}! * * @since 1.2.5 */ @@ -329,7 +359,7 @@ public String getString(String variableName) * @param defaultValue | Default value to return. * * @return String value of variable with name or defaultValue if there is no such a one or given key contains null! - * String will be also parsed from any object using {@link Object#toString()}! + * String will be also obtained from any object using {@link String#valueOf(Object)}! * * @since 1.2.5 */ @@ -342,13 +372,13 @@ public String getString(String variableName, String defaultValue) * @param variableName | Variables name. * * @return Char value of variable with name or {@code (char) 0} if there is no such a one! - * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Char will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! * * @since 1.2.5 */ public char getChar(String variableName) { - return getChar(variableName, (char) 0); + return getChar(variableName, '\0'); } /** @@ -356,7 +386,7 @@ public char getChar(String variableName) * @param defaultValue | Default value to return. * * @return Char value of variable with name or defaultValue if there is no such a one or given key contains null! - * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Char will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! * * @since 1.2.5 */ @@ -365,11 +395,9 @@ public char getChar(String variableName, char defaultValue) Object obj = get(variableName, defaultValue); if (obj instanceof Character) return (char) obj; - else if (obj instanceof CharSequence) - return ((CharSequence) obj).charAt(0); - else if (obj instanceof Number) + if (obj instanceof Number) return (char) ((Number) obj).intValue(); - return (char) obj; + return obj.toString().charAt(0); } /** @@ -390,7 +418,7 @@ public boolean getBool(String variableName) * @param defaultValue | Default value to return. * * @return Boolean value of variable with name or defaultValue if there is no such a one or given key contains null! - * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible! + * Boolean will be also parsed from {@link Number}, or {@link Object#toString()} if possible! * * @since 1.2.5 */ @@ -399,17 +427,13 @@ public boolean getBool(String variableName, boolean defaultValue) Object obj = get(variableName, defaultValue); if (obj instanceof Boolean) return (boolean) obj; - else if (obj instanceof Number) - return ((Number) obj).doubleValue() > 0; - else - { - String str = obj.toString(); - if (str.equalsIgnoreCase("t")) - return true; - else if (str.equalsIgnoreCase("f")) - return false; - return Boolean.parseBoolean(obj.toString()); - } + if (obj instanceof Number) + return ((Number) obj).doubleValue() != 0; + + String str = obj.toString(); + int len; + return (str.charAt(0) | ' ') == 't' && ((len = str.length()) == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4)); +// return Boolean.parseBoolean(str); } /** @@ -417,7 +441,9 @@ else if (str.equalsIgnoreCase("f")) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent byte value with valueIndex. - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -431,7 +457,9 @@ public byte getByte(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent short value with valueIndex. - * Byte will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Byte will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -445,7 +473,9 @@ public short getShort(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent int value with valueIndex. - * Int will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Int will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -459,7 +489,9 @@ public int getInt(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent long value with valueIndex. - * Long will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Long will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -473,7 +505,9 @@ public long getLong(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent float value with valueIndex. - * Float will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Float will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -487,7 +521,9 @@ public float getFloat(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent double value with valueIndex. - * Double will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Double will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! + * + * @throws NumberFormatException if string form of an object can't be parsed to a number! * * @since 1.2.5 */ @@ -496,11 +532,9 @@ public double getDouble(int valueIndex) Object obj = get(valueIndex); if (obj instanceof Number) return ((Number) obj).doubleValue(); - else if (obj instanceof Character) + if (obj instanceof Character) return (double) (char) obj; - else if (obj instanceof CharSequence) - return Double.parseDouble(obj.toString()); - return (double) obj; + return obj == null ? 0 : Double.parseDouble(obj.toString()); } /** @@ -522,7 +556,7 @@ public String getString(int valueIndex) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent char value with valueIndex. - * Char will be also parsed from {@link Number}, {@link Character} or {@link CharSequence} if possible! + * Char will be also parsed from {@link Number}, {@link Character} or {@link Object#toString()} if possible! * * @since 1.2.5 */ @@ -531,11 +565,9 @@ public char getChar(int valueIndex) Object obj = get(valueIndex); if (obj instanceof Character) return (char) obj; - else if (obj instanceof CharSequence) - return ((CharSequence) obj).charAt(0); - else if (obj instanceof Number) + if (obj instanceof Number) return (char) ((Number) obj).intValue(); - return (char) obj; + return obj == null ? 0 : obj.toString().charAt(0); } /** @@ -543,7 +575,7 @@ else if (obj instanceof Number) * {@link IndexOutOfBoundsException} will be thrown if index is too big! * * @return Independent boolean value with valueIndex. - * Boolean will be also parsed from {@link Number}, or {@link CharSequence} if possible! + * Boolean will be also parsed from {@link Number}, or {@link Object#toString()} if possible! * * @since 1.2.5 */ @@ -552,17 +584,12 @@ public boolean getBool(int valueIndex) Object obj = get(valueIndex); if (obj instanceof Boolean) return (boolean) obj; - else if (obj instanceof Number) - return ((Number) obj).doubleValue() > 0; - else - { - String str = obj.toString(); - if (str.equalsIgnoreCase("t")) - return true; - else if (str.equalsIgnoreCase("f")) - return false; - return Boolean.parseBoolean(obj.toString()); - } + if (obj instanceof Number) + return ((Number) obj).doubleValue() != 0; + + String str = String.valueOf(obj); + int len; + return (str.charAt(0) | ' ') == 't' && ((len = str.length()) == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4)); } /** @@ -876,21 +903,21 @@ else if (includeSubScopes) } /** - * @param objCls | Class of object to instantiate! + * @param objCls | Class of object to instantiate! Can also be {@link ParameterizedType}! * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! PropertyDescriptors of these fields will be obtained using Scope.getPropertyDescriptorsOf(Class, String)! This is used only as a last (default) option! * - * @return New instance of object according to {@link GenericScope#intoNew(Class, GenericScope, String...)} similarly to {@link GenericScope#toObject(Class)} except this one will not use any protocols! + * @return New instance of object according to {@link GenericScope#intoNew(Type, GenericScope, String...)} similarly to {@link GenericScope#toObject(Class)} except this one will not use any protocols! * * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! * - * @see Scope#intoNew(Class, GenericScope, String...) + * @see Scope#intoNew(Type, GenericScope, String...) * * @since 1.3.5 */ - public T into(Class objCls, String... fieldNamesToUse) throws IntrospectionException, Exception + public T into(Type objCls, String... fieldNamesToUse) throws IntrospectionException, Exception { - return (T) intoNew(objCls, this, fieldNamesToUse); + return intoNew(objCls, this, fieldNamesToUse); } /** @@ -902,7 +929,7 @@ public T into(Class objCls, String... fieldNamesToUse) throws Introspecti * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often)! * @throws IntrospectionException when there were no {@link PropertyDescriptor} found for obj class! * - * @see Scope#intoNew(Class, GenericScope, String...) + * @see Scope#intoNew(Type, GenericScope, String...) * * @since 1.3.5 */ @@ -1026,7 +1053,7 @@ public static Scope from(Object obj, List fieldsToUse) throw } /** - * @param objCls | Class of object to instantiate! + * @param type | Class of object to instantiate! Can also be {@link ParameterizedType}! * @param fromScope | Source scope with data to instantiate from! * @param fieldNamesToUse | Array of objCls field names to map/populate instantiated object from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! * @@ -1074,17 +1101,20 @@ New object instance (return) * @since 1.3.5 */ @SuppressWarnings("unchecked") - public static T intoNew(Class objCls, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception + public static T intoNew(Type type, GenericScope fromScope, String... fieldNamesToUse) throws IntrospectionException, Exception { - if (objCls == null) + if (type == null) return null; - if (objCls.isArray()) + boolean isGenricType; + Class objCls = (Class) ((isGenricType = type instanceof ParameterizedType) ? ((ParameterizedType) type).getRawType() : type); + Class elmType; + if ((elmType = objCls.getComponentType()) != null) { - if (objCls.getComponentType() == Object.class) + if (elmType == Object.class) return (T) fromScope.toArray(); - return (T) into(Array.newInstance(objCls.getComponentType(), fromScope.valuesCount()), fromScope, fieldNamesToUse); + return (T) into(Array.newInstance(elmType, fromScope.valuesCount()), fromScope, fieldNamesToUse); } if (GenericScope.class.isAssignableFrom(objCls)) @@ -1092,6 +1122,12 @@ public static T intoNew(Class objCls, GenericScope fro GenericScope result = ((GenericScope) fromScope).clone((Class>)objCls); if (fieldNamesToUse != null && fieldNamesToUse.length > 0) result.variables().keySet().retainAll(Arrays.asList(fieldNamesToUse)); + + if (isGenricType) + { + intoGeneric(result.values(), (ParameterizedType) type); + intoGeneric(result.variables(), (ParameterizedType) type); + } return (T) result; } @@ -1099,7 +1135,8 @@ public static T intoNew(Class objCls, GenericScope fro { if (Collection.class.isAssignableFrom(objCls)) { - return (T) fromScope.toValList(); + List list = fromScope.toValList(); + return (T) (isGenricType ? intoGeneric(list, (ParameterizedType) type) : list); } if (Map.class.isAssignableFrom(objCls)) @@ -1107,11 +1144,25 @@ public static T intoNew(Class objCls, GenericScope fro Map map = fromScope.toVarMap(); if (fieldNamesToUse != null && fieldNamesToUse.length > 0) map.keySet().retainAll(Arrays.asList(fieldNamesToUse)); - return (T) map; + return (T) (isGenricType ? intoGeneric(map, (ParameterizedType) type) : map); + } + } + + T newObj = into(Instantiate(objCls), fromScope, fieldNamesToUse); + if (isGenricType) + { + if (newObj instanceof List) + return (T) intoGeneric((List) newObj, (ParameterizedType) type); + if (newObj instanceof Map) + return (T) intoGeneric((Map) newObj, (ParameterizedType) type); + if (newObj instanceof GenericScope) + { + intoGeneric(((GenericScope) newObj).values(), (ParameterizedType) type); + intoGeneric(((GenericScope) newObj).variables(), (ParameterizedType) type); } } - return into(Instantiate(objCls), fromScope, fieldNamesToUse); + return newObj; } /** @@ -1168,10 +1219,15 @@ public static T into(T obj, GenericScope fromScope, Strin { if (obj == null) return null; - if (obj.getClass().isArray()) + + Class elmType; + if ((elmType = obj.getClass().getComponentType()) != null) { for (int i = 0, arrLen = Array.getLength(obj), scSize = fromScope.valuesCount(); i < arrLen && i < scSize; i++) - Array.set(obj, i, fromScope.get(i)); + { + Object elm = fromScope.get(i); + Array.set(obj, i, elm instanceof GenericScope && elmType != elm.getClass() ? ((GenericScope) elm).toObject(elmType) : elm); + } return obj; } @@ -1216,16 +1272,90 @@ public static T into(T obj, GenericScope fromScope, List< { for (PropertyDescriptor var : fieldsToUse) { - Object varValue = ((GenericScope) fromScope).get(var.getName(), VOID); - if (varValue != VOID) - var.getWriteMethod().invoke(obj, varValue); + Object varValue; + if ((varValue = ((GenericScope) fromScope).variables().getOrDefault(var.getName(), VOID)) != VOID) + { + Method setter = var.getWriteMethod(); + Type expectedType = setter.getGenericParameterTypes()[0]; + setter.invoke(obj, varValue instanceof GenericScope && expectedType != varValue.getClass() ? ((GenericScope) varValue).toObject(expectedType) : varValue); + } } return obj; } + /** + * @param listToGenerify | List to modify/map its elements into specified type. + * @param genericType | Requested type of lists elements. + * + * @return The same list after its {@link GenericScope} elements were turned into elements of provided genericType. If generic type can't be inferred, the whole process will stop. + * + * @throws Exception if Scope#intoNew(Type, GenericScope, String...) fails... + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public static List intoGeneric(List listToGenerify, ParameterizedType genericType) throws Exception + { + try + { + if (listToGenerify.isEmpty()) + return (List) listToGenerify; + + ListIterator iter = listToGenerify.listIterator(0); + Type elmType; + do + { + Object obj; + if ((obj = iter.next()) instanceof GenericScope) + { + iter.set(((GenericScope) obj).toObject(elmType = ((ParameterizedType) genericType).getActualTypeArguments()[0])); + + while (iter.hasNext()) + if ((obj = iter.next()) instanceof GenericScope) + iter.set(((GenericScope) obj).toObject(elmType)); + break; + } + } + while (iter.hasNext()); + } + catch (ClassCastException | IndexOutOfBoundsException e) + {} + return (List) listToGenerify; + } + + /* + * @param listToGenerify | Map whose values should be modify/map its elements into specified type. + * @param genericType | Requested type of lists elements. + * + * @return The same map after its {@link GenericScope} values were turned into values of provided genericType. If generic type can't be inferred, the whole process will stop. + * + * @throws Exception if Scope#intoNew(Type, GenericScope, String...) fails... + * + * @since 1.3.7 + */ + @SuppressWarnings("unchecked") + public static Map intoGeneric(Map mapToGenerify, ParameterizedType genericType) throws Exception + { + try + { + if (mapToGenerify.size() < 1) + return (Map) mapToGenerify; + Type elmType = ((ParameterizedType) genericType).getActualTypeArguments()[1]; //0 = key, 1 = val + for (Map.Entry entry : mapToGenerify.entrySet()) + { + Object obj; + if ((obj = entry.getValue()) instanceof GenericScope) + entry.setValue(((GenericScope) obj).toObject(elmType)); + } + } + catch (ClassCastException | IndexOutOfBoundsException e) + {} + return (Map) mapToGenerify; + } + /** * @param cls | Class to inspect! - * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all not-static and not-transient fields with public getters and setters that will be obtained! * * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! * @@ -1237,14 +1367,13 @@ public static T into(T obj, GenericScope fromScope, List< */ public static List getPropertyDescriptorsOf(Class cls, String... fieldNames) throws IntrospectionException { - return getPropertyDescriptorsOf(cls, null, fieldNames); + return getPropertyDescriptorsOf(cls, null, fieldNames); } - /** * @param cls | Class to inspect! * @param cache | Cache to store generated results into! - * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields with public getters and setters will be obtained! + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all not-static and not-transient fields with public getters and setters that will be obtained! * * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! * @@ -1255,39 +1384,56 @@ public static List getPropertyDescriptorsOf(Class cls, St * @since 1.3.5 */ public static List getPropertyDescriptorsOf(Class cls, Map, List> cache, String... fieldNames) throws IntrospectionException + { + return getPropertyDescriptorsOf(cls, null, Modifier.STATIC | Modifier.TRANSIENT, fieldNames); + } + + /** + * @param cls | Class to inspect! + * @param cache | Cache to store generated results into! + * @param modifiersToIgnore | If field has this {@link Modifier} it will not be included. Only works when fieldNames are null or empty and cache is not provided. + * @param fieldNames | Names of fields to get descriptors for, if this array is empty or null, descriptors for all fields that do not have modifiersToIgnore and have public getters and setters that will be obtained! + * + * @return List of {@link PropertyDescriptor}s of cls representing access methods of required fields! Only descriptors of fields that have valid and public getter and setter will be returned! + * + * @throws IntrospectionException when there are no suitable fields with valid and public getters and setters. + * + * @see PropertyDescriptor + * + * @since 1.3.7 + */ + public static List getPropertyDescriptorsOf(Class cls, Map, List> cache, int modifiersToIgnore, String... fieldNames) throws IntrospectionException { List fieldDescriptors = new ArrayList<>(), cached = cache == null ? null : cache.get(cls); - if (cached != null) - return cached; - - if (fieldNames == null || fieldNames.length <= 0) + if (cached != null) + return cached; + + if (fieldNames == null || fieldNames.length <= 0) { for (Class c = cls; c != Object.class; c = c.getSuperclass()) for (Field field : c.getDeclaredFields()) - if (!Modifier.isStatic(field.getModifiers())) + if ((field.getModifiers() & modifiersToIgnore) == 0) try { fieldDescriptors.add(new PropertyDescriptor(field.getName(), cls)); } catch (Exception e) {} - + if (cache != null && !fieldDescriptors.isEmpty()) - { cache.put(cls, fieldDescriptors); - } } - else - { + else + { for (int i = 0; i < fieldNames.length; i++) try - { + { fieldDescriptors.add(new PropertyDescriptor(fieldNames[i], cls)); - } - catch (Exception e) - {} - } - + } + catch (Exception e) + {} + } + if (fieldDescriptors.isEmpty()) throw new IntrospectionException("No suitable fields with valid and public getters and setters to use in " + cls.getSimpleName()); return fieldDescriptors; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index a5bc254..07f0b61 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -19,6 +19,7 @@ import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; +import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; @@ -158,8 +159,17 @@ public T toObjectOf(String variableWithscope, Class objClass, T defaultVa return toObjectOf(variableWithscope, objClass, defaultValue, getProtocols()); } + /** + * @param type | Class of object to create. + * + * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in this {@link Serializer#getProtocols()}! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ @Override - public T toObject(Class objClass) throws Exception + public T toObject(Type objClass) throws Exception { return toObject(objClass, getProtocols()); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 59a1be7..e92a264 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -184,7 +184,7 @@ public CharSequence toString(Object obj, Object... args) } } - LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + LogProvider.instance.logErr("Unable to convert \"" + (obj == null ? "null" : obj.getClass().getName()) + "\" to string because none of registered converters were aplicable for this object!", null); return null; } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 09ac8ab..0a33ab2 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -166,6 +166,8 @@ public S LoadFrom(Reader reader, Object... formatArgs) { Scope sc = super.LoadFrom(reader, formatArgs); + if (formatArgs.length > 0 && formatArgs[0] instanceof Serializer) + return (S) sc; Object jsonScope; if (sc.valuesCount() == 1 && (jsonScope = sc.get(0)) instanceof Scope) return (S) jsonScope; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index 1807b9e..09091ec 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.json.converters; +import java.util.Map; + import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.Utils; @@ -21,18 +23,23 @@ public class JsonObjectConverter extends ObjectConverter public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) { if (arg.getClass().isArray()) - arg = new Scope(Utils.fromAmbiguousArray(arg)); + return super.toString(myHomeRegistry, new Scope(Utils.fromAmbiguousArray(arg)), args); + + if (arg instanceof Map) + { + Map map = (Map) arg; + if (map.isEmpty() || map.keySet().iterator().next() instanceof CharSequence) + return super.toString(myHomeRegistry, new Scope((Map) map), args); + } SerializationProtocol prot = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args); - if (prot != null && !(arg instanceof Scope)) try { Object[] objArgs = prot.serialize(arg); if (objArgs.length == 1 && objArgs[0] instanceof Scope) return super.toString(myHomeRegistry, objArgs[0], args); - else - return super.toString(myHomeRegistry, new Scope(objArgs), args); + return super.toString(myHomeRegistry, new Scope(objArgs), args); } catch (Exception e) {} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index 1f869ed..5028812 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -4,10 +4,13 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; -import java.util.ArrayList; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Arrays; import java.util.HashMap; import java.util.List; +import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.protocols.SerializationProtocol; @@ -24,8 +27,9 @@ */ public class AutoProtocol extends SerializationProtocol { - static { - UNIVERSAL_INTROSPECTION = new ArrayList<>(); + static + { + UNIVERSAL_INTROSPECTION = Arrays.asList(); } /** @@ -55,7 +59,7 @@ public class AutoProtocol extends SerializationProtocol public static final List UNIVERSAL_INTROSPECTION; protected final Class applicableFor; - protected List fieldDescriptors = new ArrayList<>(); + protected List fieldDescriptors; protected HashMap, List> cache = new HashMap<>(); protected boolean useScope; @@ -94,7 +98,7 @@ public AutoProtocol(Class applicableFor, List fieldsToSer */ public AutoProtocol(Class applicableFor, boolean useScope, String... fieldsToSerialize) throws IntrospectionException { - this(applicableFor, useScope, fieldsToSerialize.length == 0 ? UNIVERSAL_INTROSPECTION : Scope.getPropertyDescriptorsOf(applicableFor, fieldsToSerialize)); + this(applicableFor, useScope, fieldsToSerialize == null || fieldsToSerialize.length == 0 ? UNIVERSAL_INTROSPECTION : Scope.getPropertyDescriptorsOf(applicableFor, fieldsToSerialize)); } /** @@ -109,13 +113,13 @@ public AutoProtocol(Class applicableFor, boolean useScope, List objectClass) throws Exception @Override public Object[] serialize(T object) throws Exception { - List fieldDescriptors = this.fieldDescriptors; + List fieldDescriptors = getFieldDescriptors(); if (fieldDescriptors == UNIVERSAL_INTROSPECTION) fieldDescriptors = Scope.getPropertyDescriptorsOf(object.getClass(), cache); if (isUseScope()) - { return new Object[] {Scope.from(object, fieldDescriptors)}; - } - else - { - int size = fieldDescriptors.size(); - Object[] args = new Object[size]; - for (int i = 0; i < size; i++) - args[i] = fieldDescriptors.get(i).getReadMethod().invoke(object); - return args; - } + + int size = fieldDescriptors.size(); + Object[] args = new Object[size]; + for (int i = 0; i < size; i++) + args[i] = fieldDescriptors.get(i).getReadMethod().invoke(object); + return args; } + @SuppressWarnings("unchecked") @Override public T unserialize(Class objectClass, Object... args) throws Exception { - List fieldDescriptors = this.fieldDescriptors; + List fieldDescriptors = getFieldDescriptors(); if (fieldDescriptors == UNIVERSAL_INTROSPECTION) fieldDescriptors = Scope.getPropertyDescriptorsOf(objectClass, cache); @@ -167,25 +168,24 @@ public T unserialize(Class objectClass, Object... args) throws Exce return Scope.into(obj, (Scope) args[0], fieldDescriptors); } - for (int i = 0, size = fieldDescriptors.size(); i < size && i < args.length; i++) - fieldDescriptors.get(i).getWriteMethod().invoke(obj, args[i]); + for (int i = 0, size = fieldDescriptors.size(); i < size && i < args.length; i++) + { + Method setter = fieldDescriptors.get(i).getWriteMethod(); + Type expectedType = setter.getGenericParameterTypes()[0]; + setter.invoke(obj, args[i] instanceof GenericScope && expectedType != args[i].getClass() ? ((GenericScope) args[i]).toObject(expectedType) : args[i]); + } return obj; } /** - * @param variableName | Name of variable! - * - * @return PropertyDescriptor of variable with name or null if this protocols can't serialize variable with given name!
- * Note: I would recommend to tread this as read only and not set anything that you are not sure of. This will ensure correct functionality... + * @return PropertyDescriptors of variables that are used by this protocol!
+ * Note: I would recommend to tread this as read only and not modify anything that you are not sure of. This will ensure correct functionality of this protocol... * * @since 1.3.2 */ - public PropertyDescriptor getfieldDescriptorsDescriptor(String variableName) + public List getFieldDescriptors() { - for (PropertyDescriptor var : fieldDescriptors) - if (var.getName().equals(variableName)) - return var; - return null; + return this.fieldDescriptors; } @Override diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index a773ea9..22a8e25 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -1,8 +1,10 @@ package org.ugp.serialx.juss.protocols; import java.lang.reflect.Constructor; +import java.lang.reflect.Type; import java.util.Arrays; +import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; import org.ugp.serialx.Utils; import org.ugp.serialx.protocols.SerializationProtocol; @@ -42,19 +44,42 @@ public Object[] serialize(T object) @Override public T unserialize(Class objectClass, Object... args) throws Exception { - try + try { return objectClass.getConstructor(Utils.ToClasses(args)).newInstance(args); } catch (Exception e0) { - for (Constructor cons : objectClass.getConstructors()) - try - { - return (T) cons.newInstance(args); - } - catch (IllegalArgumentException e) - {} + int argCount = args.length; + for (Constructor cons : objectClass.getConstructors()) + if (cons.getParameterCount() == argCount) + try + { + return (T) cons.newInstance(args); + } + catch (IllegalArgumentException e) + { + try + { + for (int i = 0; i < argCount; i++) + { + Object arg; + if ((arg = args[i]) instanceof GenericScope) + { + Type[] paramTypes; + args = args.clone(); + args[i] = ((GenericScope) arg).toObject((paramTypes = cons.getGenericParameterTypes())[i]); + + for (i++; i < argCount; i++) + if ((arg = args[i]) instanceof GenericScope) + args[i] = ((GenericScope) arg).toObject(paramTypes[i]); + return (T) cons.newInstance(args); + } + } + } + catch (IllegalArgumentException e2) + {} + } } LogProvider.instance.logErr("Unable to create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); return null; From c50659deeb21f39d5a8f482fb6e021f32d0cd9a5 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 20 Jul 2024 19:53:22 +0200 Subject: [PATCH 33/75] finishing.... --- .../serialx/juss/protocols/SelfSerializableProtocol.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index efa1aaa..a4317af 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -9,7 +9,7 @@ * * @see UniversalObjectInstantiationProtocol */ -public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol +public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol { /** * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
@@ -17,13 +17,13 @@ public class SelfSerializableProtocol extends UniversalObjectInstantiationProtoc * * @since 1.3.7 */ - public SelfSerializableProtocol(Class applicableFor) + public SelfSerializableProtocol(Class applicableFor) { super(applicableFor); } @Override - public Object[] serialize(SelfSerializable object) + public Object[] serialize(T object) { return object.serialize(); } From 6743767a5033e424e622735f7acd13b926944a4e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 31 Jul 2024 21:29:16 +0200 Subject: [PATCH 34/75] Small refactor of ArrConv, improving performance and security of OpGroups, DataRegi is now DataParser --- .../src/main/java/org/ugp/serialx/Utils.java | 4 +- .../ugp/serialx/converters/DataParser.java | 33 ++++++-- .../juss/converters/ArrayConverter.java | 45 ++++++----- .../juss/converters/OperationGroups.java | 76 +++++++++++-------- 4 files changed, 98 insertions(+), 60 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index f7eae53..024a320 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -820,8 +820,8 @@ public static String showPosInString(CharSequence str, int pos) */ public static Object castArray(Object[] sourceArray, Class toType) { - int len = sourceArray.length; - Object arr = Array.newInstance(ToClasses(toType)[0], len); + int len; + Object arr = Array.newInstance(ToClasses(toType)[0], len = sourceArray.length); for (int i = 0; i < len; i++) Array.set(arr, i, sourceArray[i]); return arr; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index e92a264..e215655 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -75,7 +75,7 @@ public static Object parseObj(String str, Object... args) * * @since 1.3.5 */ - public static class ParserRegistry extends Registry + public static class ParserRegistry extends Registry implements DataParser { private static final long serialVersionUID = -2598324826689380752L; @@ -167,11 +167,11 @@ public DataConverter getConverterFor(Object obj, Object... args) */ public CharSequence toString(Object obj, Object... args) { - CharSequence str = null; + CharSequence str; if (convertingCache != null) for (DataParser parser : convertingCache) if (parser != null && (str = ((DataConverter) parser).toString(this, obj, args)) != CONTINUE) - return str; + return str; for (int i = 0, size = size(); i < size; i++) { @@ -188,6 +188,28 @@ public CharSequence toString(Object obj, Object... args) return null; } + /** + * @param parentRegistry | Registry provided by caller, but remember that {@link Registry} is also a {@link DataParser} and therefore this registry will be used instead of this argument. + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! + * If no suitable parser/result was found, {@link DataParser#CONTINUE} will be returned, as it means that this {@link Registry} was not suitable as parser!
+ * Note: If this registry contains it self as parser (which should not happen) it will attempt to skip it self in order to not cause possible infinite recursion! + * + * @see DataParser#parseObj(String, Object...) + * + * @since 1.3.7 + */ + @Override + public Object parse(ParserRegistry parentRegistry, String str, Object... args) + { + Object result; + if ((result = parse(str, true, this == parentRegistry ? getClass() : null, args)) == str) + return CONTINUE; + return result; + } + /** * @param str | Source string to parse using suitable parser from registry. * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! @@ -204,7 +226,7 @@ public Object parse(String str, Object... args) /** * @param str | Source string to parse using suitable parser from registry. - * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message! + * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message in case of suitable parser not found! * @param ignore | {@link DataParser} class to ignore! * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! * @@ -215,7 +237,7 @@ public Object parse(String str, Object... args) */ public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) { - Object obj = null; + Object obj; if (parsingCache != null) for (DataParser parser : parsingCache) if (parser != null && (ignore == null || ignore != parser.getClass()) && (obj = parser.parse(this, str, args)) != CONTINUE) @@ -345,5 +367,6 @@ public DataParser[] getConverterCache() { return convertingCache; } + } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 0849c5f..b5882bd 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -51,32 +51,35 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { if (indexOfNotInObj(str, ' ') > 0) { - boolean findArrType = true; - if (args.length > 1 && args[1] instanceof Boolean) - findArrType = (boolean) args[1]; - String[] strObjs = tokenize(str); - int len = strObjs.length; - Object[] objs = new Object[len]; + int len, i = 0; + Object[] objs = new Object[len = strObjs.length]; - Class arrClass = null; - for (int i = 0; i < len; i++) + if (args.length < 2 || !(args[1] instanceof Boolean) || (boolean) args[1]) { - Object obj = objs[i] = myHomeRegistry.parse(strObjs[i], args); - if (obj != null) - if (arrClass == null) - arrClass = obj.getClass(); - else if (arrClass != obj.getClass()) - arrClass = Object.class; - } - - if (findArrType && arrClass != null && !arrClass.equals(Object.class)) - try + Class arrClass = null; + for (; i < len; i++) { - return castArray(objs, arrClass); + Object obj = objs[i] = myHomeRegistry.parse(strObjs[i], args); + if (obj != null) + if (arrClass == null) + arrClass = obj.getClass(); + else if (arrClass != obj.getClass()) + arrClass = Object.class; } - catch (IllegalArgumentException e) - {} + + if (arrClass != null && arrClass != Object.class) + try + { + return castArray(objs, arrClass); + } + catch (IllegalArgumentException e) + {} + return objs; + } + + for (; i < len; i++) + objs[i] = myHomeRegistry.parse(strObjs[i], args); return objs; } return CONTINUE; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 9315151..f62765b 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -7,7 +7,6 @@ import java.util.Map; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataParser; /** @@ -27,46 +26,59 @@ public class OperationGroups implements DataParser { /** + * @deprecated (since 1.3.7) DO NOT USE, USE {@link OperationGroups#groupMark} instead!
+ * * Opening and closing of group mark! * * @since 1.3.0 */ - public static final String GROUP_MARK_OP = new String(new char[] {127, 128, 129}), GROUP_MARK_CLS = new String(new char[] {129, 128, 127}); + @Deprecated + public static final char[] GROUP_MARK_OP = new char[] {127, 128, 129}, GROUP_MARK_CLS = new char[] {129, 128, 127}; + + /** + * Character marking the opening of {@link OperationGroups} mark in processed string, closing should be marked as this character -1.
+ * This character is generated in sami-random fashion but it will never be an ASCII character. + * + * @since 1.3.7 + */ + protected final char groupMark = (char) (System.nanoTime() | 128); @SuppressWarnings("unchecked") @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { if (str.length() > 1) { - int opIndex = indexOfOpening(str, 0, '('), clsIndex = -1; + int opIndex = indexOfOpening(str, 0, '('), clsIndex; if (opIndex > -1 && (clsIndex = indexOfClosing(str, opIndex, new char[] {'('}, ')')) > -1) { - Map runtimeGroupStack = new HashMap<>(); + Map runtimeGroups; if (args.length > 2 && args[2] instanceof Map) - runtimeGroupStack = (Map) args[2]; + runtimeGroups = (Map) args[2]; else { if (args.length < 3) args = Arrays.copyOf(args, 3); - args[2] = runtimeGroupStack; + args[2] = runtimeGroups = new HashMap<>(); } - String mark = GROUP_MARK_OP + runtimeGroupStack.size() + GROUP_MARK_CLS; - runtimeGroupStack.put(mark, str.substring(opIndex+1, clsIndex).trim()); - StringBuilder sb = new StringBuilder(str).replace(opIndex, clsIndex+1, mark); - return myHomeRegistry.parse(sb.toString(), args); + int groupId; + runtimeGroups.put(groupId = runtimeGroups.size(), str.substring(opIndex+1, clsIndex).trim()); + + StringBuilder newStr = new StringBuilder(str).replace(opIndex, clsIndex+1, new StringBuilder().append(groupMark).append(groupId).append((char) (groupMark-1)).toString()); + return myHomeRegistry.parse(newStr.toString(), args); } - if (isGroupMark(str)) + int groupId; + if ((groupId = isGroupMark(str, groupMark)) != -1) { if (args.length > 2 && args[2] instanceof Map) { - Map runtimeGroupStack = (Map) args[2]; + Map runtimeGroups = (Map) args[2]; Object[] newArgs = args.clone(); - newArgs[2] = new HashMap(); - return myHomeRegistry.parse(runtimeGroupStack.get(str), newArgs); + newArgs[2] = new HashMap(); + return myHomeRegistry.parse(runtimeGroups.get(groupId), newArgs); } LogProvider.instance.logErr("Runtime group stack is trying to be accessed using " + str + " however it was not provided yet!", null); return null; @@ -78,30 +90,30 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) /** * @param s | Char sequence to check! + * @param groupMark | Opening character identifying this group mark, closing should be this character -1 * - * @return Return true if inserted CharSequence match the runtime group mark wrapper! + * @return Id of the group mark if inserted CharSequence matches the runtime group mark wrapper format! -1 otherwise.
* This is used for internal purposes of {@link OperationGroups}. * * @since 1.3.0 */ - public static boolean isGroupMark(CharSequence s) + public static int isGroupMark(CharSequence s, char groupMark) { - String op = GROUP_MARK_OP, cls = GROUP_MARK_CLS; - int lo = op.length(), lc = cls.length(), len = s.length(); - if (len < lo + lc + 1) - return false; - for (int i = 0; i < lo; i++) - if (s.charAt(i) != op.charAt(i)) - return false; + int i = s.length()-1; + if (i < 2 || s.charAt(0) != groupMark-- || s.charAt(i--) != groupMark) + return -1; - for (int i = lo, ch; i < len - lc; i++) + int groupId; + if ((groupId = s.charAt(i--) - '0') < 0 || groupId > 9) + return -1; + for (int ch, baseCof = 10; i >= 1; i--, baseCof *= 10) + { if ((ch = s.charAt(i)) < '0' || ch > '9') - return false; + return -1; + groupId += (ch - '0') * baseCof; + } - for (int i = 0; i < lc; i++) - if (s.charAt(len-i-1) != cls.charAt(lc-i-1)) - return false; - return true; + return groupId; } /** @@ -109,7 +121,7 @@ public static boolean isGroupMark(CharSequence s) * @param from | Beginning index of search! * @param openings | Openings to find! * - * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link Serializer#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.Utils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ @@ -145,7 +157,7 @@ else if (brackets == 0 && isOneOf(ch, openings)) * @param openings | Openings to count with! * @param closing | Closings to find! * - * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link Serializer#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.Utils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ From 7bebded8a153d7a35bb29bcd50d528e664a3d35f Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 31 Jul 2024 23:32:01 +0200 Subject: [PATCH 35/75] make it 1.3.8 --- .../java/org/ugp/serialx/GenericScope.java | 28 +++++++++---------- .../src/main/java/org/ugp/serialx/Scope.java | 6 ++-- .../main/java/org/ugp/serialx/Serializer.java | 4 +-- .../src/main/java/org/ugp/serialx/Utils.java | 10 +++---- .../ugp/serialx/converters/DataParser.java | 2 +- .../serialx/converters/NumberConverter.java | 4 +-- .../serialx/converters/ProtocolConverter.java | 10 +++---- .../serialx/converters/StringConverter.java | 8 +++--- .../serialx/converters/VariableParser.java | 6 ++-- .../converters/imports/ImportsProvider.java | 2 +- .../serialx/devtools/DebugParserRegistry.java | 2 +- .../devtools/SerializationDebugger.java | 4 +-- .../org/ugp/serialx/json/JsonSerializer.java | 2 +- .../converters/JsonCharacterConverter.java | 8 +++--- .../json/converters/JsonNumberConverter.java | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 2 +- .../juss/converters/OperationGroups.java | 4 +-- .../juss/converters/VariableConverter.java | 2 +- .../protocols/SelfSerializableProtocol.java | 2 +- .../UniversalObjectInstantiationProtocol.java | 2 +- .../org/ugp/serialx/converters/Operators.java | 10 +++---- .../operators/ArithmeticOperators.java | 8 +++--- .../operators/NegationOperator.java | 2 +- 23 files changed, 65 insertions(+), 65 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 49aa640..a47d582 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -209,7 +209,7 @@ public ValT put(KeyT variableKey, ValT variableValue) * * @return Array of values previously at keys from kv array. * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public ValT[] putAllKv(Object... kVkVkV) @@ -303,7 +303,7 @@ public V get(KeyT variableKey, V defaultValue) * If there is no other variable called "value" in the scope tree then you can also simplify it to scope.get("value"), but make sure that there is no equally-named variable!
* Note: Make sure that you are not calling {@link GenericScope#get(Object, Object)} by accident when you are using inline vargas array (unspecified count of arguments)! * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public V get(KeyT... pathToValue) @@ -341,7 +341,7 @@ public V get(KeyT... pathToValue) * * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)} * - * @since 1.3.7 + * @since 1.3.8 */ public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception { @@ -370,7 +370,7 @@ public boolean containsVariable(KeyT variableKey) * * @return True if independent value was found in this scope. * - * @since 1.3.7 + * @since 1.3.8 */ @Override public boolean contains(Object value) @@ -415,7 +415,7 @@ public V get(int valueIndex) * * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! * - * @since 1.3.7 + * @since 1.3.8 */ public V get(int valueIndex, Class cls) throws Exception { @@ -475,7 +475,7 @@ public boolean addAll(@SuppressWarnings("unchecked") ValT... values) * * @return True all provided values are contained in this scope as independent values! * - * @since 1.3.7 + * @since 1.3.8 */ @Override public boolean containsAll(Collection values) @@ -488,7 +488,7 @@ public boolean containsAll(Collection values) * * @return {@link Collection#removeAll(Collection)} for the independent values,,, * - * @since 1.3.7 + * @since 1.3.8 */ @Override public boolean removeAll(Collection values) @@ -501,7 +501,7 @@ public boolean removeAll(Collection values) * * @return {@link Collection#retainAll(Collection)} for the independent values,,, * - * @since 1.3.7 + * @since 1.3.8 */ @Override public boolean retainAll(Collection values) @@ -774,7 +774,7 @@ public ValT remove(int valueIndex) * * @return Value of variable that was removed! * - * @since 1.3.7 + * @since 1.3.8 */ @Override public boolean remove(Object independentValue) @@ -787,7 +787,7 @@ public boolean remove(Object independentValue) * * @return Value of variable that was removed! * - * @since 1.3.7 + * @since 1.3.8 */ public ValT removeVariable(KeyT variableKey) { @@ -869,7 +869,7 @@ public int variablesCount() /** * @return Total number of variables and independent values of this scope! (vvaluesCount() + variablesCount()) * - * @since 1.3.7 (before 1.3.7 known as totalSize) + * @since 1.3.8 (before 1.3.8 known as totalSize) */ @Override public int size() @@ -948,7 +948,7 @@ public List toValList() * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! * Modifying this list will not affect this {@link GenericScope} object! * - * @since 1.3.7 (before 1.3.7 known as toValArray) + * @since 1.3.8 (before 1.3.8 known as toValArray) */ @Override public Object[] toArray() @@ -962,7 +962,7 @@ public Object[] toArray() * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! * Modifying this list will not affect this {@link GenericScope} object! * - * @since 1.3.7 (before 1.3.7 known as toValArray) + * @since 1.3.8 (before 1.3.8 known as toValArray) */ @Override public T[] toArray(T[] vals) @@ -1088,7 +1088,7 @@ public static > S intoBidirectional(S scopeTo * * @return Same map populated with kV array. * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public static > M mapKvArray(M map, Object... kVkVkV) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index a7a9fc0..00e7652 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1291,7 +1291,7 @@ public static T into(T obj, GenericScope fromScope, List< * * @throws Exception if Scope#intoNew(Type, GenericScope, String...) fails... * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public static List intoGeneric(List listToGenerify, ParameterizedType genericType) throws Exception @@ -1331,7 +1331,7 @@ public static List intoGeneric(List listToGenerify, ParameterizedType * * @throws Exception if Scope#intoNew(Type, GenericScope, String...) fails... * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public static Map intoGeneric(Map mapToGenerify, ParameterizedType genericType) throws Exception @@ -1400,7 +1400,7 @@ public static List getPropertyDescriptorsOf(Class cls, Ma * * @see PropertyDescriptor * - * @since 1.3.7 + * @since 1.3.8 */ public static List getPropertyDescriptorsOf(Class cls, Map, List> cache, int modifiersToIgnore, String... fieldNames) throws IntrospectionException { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 07f0b61..95fd1d3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -605,7 +605,7 @@ public A SerializeAsSubscope(A source, char[] wrappingBra * * @return Object that was parsed from string at given index, using parsers of this {@link Serializer}! * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public T getParsed(int indexWithStringValue, Object... args) @@ -619,7 +619,7 @@ public T getParsed(int indexWithStringValue, Object... args) * * @return Object that was parsed from value of given variable, using parsers of this {@link Serializer}! * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public T getParsed(String variableWithStringValue, Object... args) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 024a320..52e35b2 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -30,7 +30,7 @@ * * @author PETO * - * @since 1.3.7 + * @since 1.3.8 */ public final class Utils { private Utils() {} @@ -522,7 +522,7 @@ public static String[] splitValues(String s, int limit, int splittingStrategy, c * * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! * - * @since 1.3.7 + * @since 1.3.8 */ public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) { @@ -784,7 +784,7 @@ public static boolean contains(CharSequence str, char... oneOf) * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
* Also sufficient length of both strings is not checked so adjust from and to accordingly. * - * @since 1.3.7 + * @since 1.3.8 */ public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) { @@ -852,7 +852,7 @@ public static Object[] mergeArrays(Object arr1, Object arr2) * * @throws IllegalArgumentException if the specified object is not an array! * - * @since 1.3.2 (since 1.3.7 moved from ArrayConverter) + * @since 1.3.2 (since 1.3.8 moved from ArrayConverter) */ public static Object[] fromAmbiguousArray(Object array) { @@ -912,7 +912,7 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO * * @since 1.2.2 * - * @deprecated (in 1.3.7) NO LONGER NEEDED, DO NOT USE THIS! You were never supposed to... + * @deprecated (in 1.3.8) NO LONGER NEEDED, DO NOT USE THIS! You were never supposed to... */ public static final class NULL //TODO: REMOVE IN NEXT V!!!! { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index e215655..2b7ac42 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -199,7 +199,7 @@ public CharSequence toString(Object obj, Object... args) * * @see DataParser#parseObj(String, Object...) * - * @since 1.3.7 + * @since 1.3.8 */ @Override public Object parse(ParserRegistry parentRegistry, String str, Object... args) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index e873476..2b4a998 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -155,7 +155,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob * * @return Number formated to string! * - * @since 1.3.7 + * @since 1.3.8 */ public String format(Number num) { @@ -174,7 +174,7 @@ public String format(Number num) * @return {@link Number} parsed from str with rules specified above. This function was designed to act as more optimized merger of {@link Byte#valueOf(String, int)}, {@link Short#valueOf(String, int)}, {@link Integer#valueOf(String, int)}, {@link Long#valueOf(String, int)} and {@link Float#valueOf(String)}, {@link Double#valueOf(String)} all encapsulated in 1 universal function.
* Note: This function will not check for incorrect number formats in order to save performance. Only incorrect format is when inserted string contains space, in this case it will return null! * - * @since 1.3.7 + * @since 1.3.8 */ public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index c41079c..6c8332a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -54,7 +54,7 @@ * * @author PETO * - * @since 1.3.0 (separated from ObjectConverter since 1.3.7) + * @since 1.3.0 (separated from ObjectConverter since 1.3.8) */ public class ProtocolConverter implements DataConverter { @@ -96,7 +96,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile * * @return Object od objClass parsed from str in accordance with compilerArgs! * - * @since 1.3.7 + * @since 1.3.8 */ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String str, Object... compilerArgs) { @@ -284,7 +284,7 @@ public void setUseBase64IfCan(boolean useBase64IfCan) /** * @return True if invocation of static members (:: operator) is allowed (false by default)! * - * @since 1.3.7 + * @since 1.3.8 */ public boolean isAllowStaticMemberInvocation() { @@ -294,7 +294,7 @@ public boolean isAllowStaticMemberInvocation() /** * @param allowStaticMemberInvocation | Enable/disable the invocation of static members (:: operator) (false by default)! * - * @since 1.3.7 + * @since 1.3.8 */ public void setAllowStaticMemberInvocation(boolean allowStaticMemberInvocation) { @@ -407,7 +407,7 @@ public static char[] secondarySubscopeWrappers() * @return {@link Utils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
* Note: If you are not sure what this does, preferably use {@link Utils#InvokeStaticFunc(Class, String, Object...)}! * - * @since 1.3.7 + * @since 1.3.8 */ public static Object InvokeStaticFunc(Class cls, Class oldCls, String name, Object[] args, Object... compilerArgs) { try diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 1314103..2e61b8b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -108,7 +108,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob * Recommended: Enable this when parsing a lot of strings that are the same, otherwise this will not have a big impact.
* Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! * - * @since 1.3.7 + * @since 1.3.8 */ public void setParsingCache(Map cache) { @@ -120,7 +120,7 @@ public void setParsingCache(Map cache) * Null will be returned if caching is disabled, which is by default...
* Note: Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! * - * @since 1.3.7 + * @since 1.3.8 */ public Map getParsingCache() { @@ -130,7 +130,7 @@ public Map getParsingCache() /** * @return Will return value of {@link StringConverter#serializeStringNormally}! * - * @since 1.3.7 (it was static before = not good) + * @since 1.3.8 (it was static before = not good) */ public boolean isSerializeStringNormally() { @@ -140,7 +140,7 @@ public boolean isSerializeStringNormally() /** * @param serializeStringNormally | Set value of {@link StringConverter#serializeStringNormally}! * - * @since 1.3.7 (it was static before = not good) + * @since 1.3.8 (it was static before = not good) */ public void setSerializeStringNormally(boolean serializeStringNormally) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index ba99062..0f9af02 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -18,7 +18,7 @@ * * @author PETO * - * @since 1.3.7 + * @since 1.3.8 */ public class VariableParser implements DataParser { @@ -40,7 +40,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
* Note: This method is meant to be overridden in order to add support for accessing multiple sources because by default it supports only {@link GenericScope} * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public Object getMemberOperator(Object source, Object member) @@ -58,7 +58,7 @@ public Object getMemberOperator(Object source, Object member) * * @return Value of variable read from scope is str was suitable. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. * - * @since 1.3.7 + * @since 1.3.8 */ protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java index 06a89a7..835bcc7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -22,7 +22,7 @@ public interface ImportsProvider * Cache of Classes to their respective names/aliases.
* Note: Treat as read only if possible! * - * @since 1.3.7 + * @since 1.3.8 */ public static final Map> CLASS_CACHE = new HashMap>(); diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index bc7e8e0..cf31e39 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -38,7 +38,7 @@ public DebugParserRegistry clone() * * @return Clone of this {@link DebugParserRegistry} * - * @since 1.3.7 + * @since 1.3.8 */ public DebugParserRegistry clone(boolean copyStackTrace) { diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index bcbc5c4..7a7a970 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -32,7 +32,7 @@ public class SerializationDebugger implements DataConverter * Output object that will be used for logging... * If null, it will be set automatically! * - * @since 1.3.7 + * @since 1.3.8 */ public static PrintWriter out; @@ -145,7 +145,7 @@ else if (args[99] instanceof Integer && (int) args[99] > 0) /** * Helper method for printing contents of {@link ParserRegistry#getParsingCache()}. * - * @since 1.3.7 + * @since 1.3.8 */ public static void printCacheInfo(PrintWriter out, DataParser[] cache, String cacheType, String additional) { diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 0a33ab2..a5ae395 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -257,7 +257,7 @@ public static JsonSerializer fromJussSerializer(JussSerializer jussSerializer) * * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! * - * @since 1.3.2 (since 1.3.7 moved from {@link JussSerializer} and renamed from "fromJsonSerializer" to "toJussSerializer") + * @since 1.3.2 (since 1.3.8 moved from {@link JussSerializer} and renamed from "fromJsonSerializer" to "toJussSerializer") */ public static JussSerializer toJussSerializer(JsonSerializer jsonSerializer) { diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java index d9fc561..9067423 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java @@ -7,7 +7,7 @@ * * @author PETO * - * @since 1.3.7 + * @since 1.3.8 */ public class JsonCharacterConverter extends CharacterConverter { @@ -16,7 +16,7 @@ public class JsonCharacterConverter extends CharacterConverter /** * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). * - * @since 1.3.7 + * @since 1.3.8 */ public JsonCharacterConverter(boolean formatAsString) { @@ -34,7 +34,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. /** * @return True if character is going to be serialized in a letter form. If false, it will be serialized as ASCII value (int). * - * @since 1.3.7 + * @since 1.3.8 */ public boolean isFormatAsString() { @@ -44,7 +44,7 @@ public boolean isFormatAsString() /** * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). * - * @since 1.3.7 + * @since 1.3.8 */ public void setFormatAsString(boolean formatAsString) { diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java index 0f2e76e..402f0e8 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -7,7 +7,7 @@ * * @author PETO * - * @since 1.3.7 + * @since 1.3.8 */ public class JsonNumberConverter extends NumberConverter { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 939f75e..ce5faab 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -67,7 +67,7 @@ public class JussSerializer extends Serializer implements ImportsProvider /** * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. *
- * Since 1.3.7 this requires "org.ugp.serialx.converters.Operators" from SerialX "operators" modules to be present on the classpath! + * Since 1.3.8 this requires "org.ugp.serialx.converters.Operators" from SerialX "operators" modules to be present on the classpath! * * @since 1.3.2 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index f62765b..56f4331 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -26,7 +26,7 @@ public class OperationGroups implements DataParser { /** - * @deprecated (since 1.3.7) DO NOT USE, USE {@link OperationGroups#groupMark} instead!
+ * @deprecated (since 1.3.8) DO NOT USE, USE {@link OperationGroups#groupMark} instead!
* * Opening and closing of group mark! * @@ -39,7 +39,7 @@ public class OperationGroups implements DataParser * Character marking the opening of {@link OperationGroups} mark in processed string, closing should be marked as this character -1.
* This character is generated in sami-random fashion but it will never be an ASCII character. * - * @since 1.3.7 + * @since 1.3.8 */ protected final char groupMark = (char) (System.nanoTime() | 128); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 9d281e1..a322a66 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -163,7 +163,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDe * * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link VOID} should be returned! * - * @since 1.3.7 + * @since 1.3.8 */ @SuppressWarnings("unchecked") public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, String member, Object val, boolean genericVar, Object... args) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index a4317af..3afe55f 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -15,7 +15,7 @@ public class SelfSerializableProtocol extends Univer * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
* Note: Passing {@link SelfSerializable#getClass()} will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered unsafe in some cases... * - * @since 1.3.7 + * @since 1.3.8 */ public SelfSerializableProtocol(Class applicableFor) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index 22a8e25..cf60821 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -27,7 +27,7 @@ public class UniversalObjectInstantiationProtocol extends SerializationProtoc * @param applicableFor | Class that can be serialized using this protocol. * Note: Passing {@link Object#getClass()} will make this protocol universal and work for any {@link Object} instance, this can be considered unsafe in some cases... * - * @since 1.3.7 + * @since 1.3.8 */ public UniversalObjectInstantiationProtocol(Class applicableFor) { diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java index 64c0c9f..e0aa691 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java @@ -14,7 +14,7 @@ * * @see Operators#install(ParserRegistry) * - * @since 1.3.7 + * @since 1.3.8 * * @author PETO */ @@ -28,7 +28,7 @@ public class Operators { * {@link ArithmeticOperators}
* In given order! * - * @since 1.3.7 + * @since 1.3.8 */ public static final DataParser[] BINARY = { new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators() }; @@ -37,7 +37,7 @@ public class Operators { * {@link NegationOperator}
* In given order! * - * @since 1.3.7 + * @since 1.3.8 */ public static final DataParser[] UNARY = { new NegationOperator() }; @@ -46,7 +46,7 @@ public class Operators { * * @return The same registry with operators inserted! * - * @since 1.3.7 + * @since 1.3.8 */ public static ParserRegistry install(ParserRegistry registry) { registry.addAllBefore(StringConverter.class, true, BINARY); @@ -59,7 +59,7 @@ public static ParserRegistry install(ParserRegistry registry) { * * @return The same registry with no more operators! * - * @since 1.3.7 + * @since 1.3.8 */ public static ParserRegistry uninstall(ParserRegistry registry) { registry.removeAll(Arrays.asList(BINARY)); diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 62f7bf7..8508845 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -31,7 +31,7 @@ public class ArithmeticOperators implements DataParser /** * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator(Object, String, Object)}.
Intended for override, should not be null or empty! * - * @since 1.3.7 + * @since 1.3.8 */ protected char[] operators = {'+', '-', '*', '/', '%'}; @@ -97,7 +97,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * * @return Result of binary operation described by op between opr1 and opr2! If operator is not known, opr1 will be returned by default! * - * @since 1.3.7 + * @since 1.3.8 */ public Object operator(Object opr1, String op, Object opr2) { @@ -125,7 +125,7 @@ public Object operator(Object opr1, String op, Object opr2) * * @return Priority of provided operator (higher number = higher priority, 2 = high, 1 = medium, 0 = low) * - * @since 1.3.7 + * @since 1.3.8 */ public byte getOperatorPriority(String op) { @@ -395,7 +395,7 @@ public static Object pow(Object cof, Object cof2, int sign) * * @return Array with 2 lists. Index 0 is {@link ArrayList} containing parsed operands of the expression, index 1 is {@link LinkedList} containing operators of the expression! * - * @since 1.3.7 (originally getTerms since 1.3.0) + * @since 1.3.8 (originally getTerms since 1.3.0) */ @SuppressWarnings("unchecked") public static List[] getAndParseTerms(String str, int to, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs) diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java index 99f6702..2f727bb 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -55,7 +55,7 @@ public Object notOperator(Object obj) * @return Negated object supposed to be returned or same object as argument if object can't be negated! Should, but do not strictly has to be boolean!
* Node: By default it has same behavior as {@link NegationOperator#notOperator(Object)} but it can be overridden! * - * @since 1.3.7 + * @since 1.3.8 */ public Object logicalNotOperator(Object obj) { From 6b93039678956eac21cb41b1a373ea04a55990e4 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 4 Aug 2024 16:19:45 +0200 Subject: [PATCH 36/75] poms --- SerialX-core/pom.xml | 2 +- .../ugp/serialx/converters/ProtocolConverter.java | 13 ++++--------- SerialX-devtools/pom.xml | 2 +- .../java/org/ugp/serialx/json/JsonSerializer.java | 4 +--- .../ugp/serialx/juss/converters/ArrayConverter.java | 7 ++----- .../serialx/juss/converters/VariableConverter.java | 6 ++---- 6 files changed, 11 insertions(+), 23 deletions(-) diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index 561fa3b..fec3b0e 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -11,5 +11,5 @@ 1.3.7 SerialX core - Core of SerialX + Core of SerialX. Contains core features and utilities shared across the library. \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 6c8332a..a5a5a3c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -190,23 +190,18 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) { - Object[] objArgs; Class oldObjectClass = null; try { - int tabs = 0, index = 0; - if (args.length > 1 && args[1] instanceof Integer) - tabs = (int) args[1]; - - if (args.length > 2 && args[2] instanceof Integer) - index = (int) args[2]; + int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; + int index = args.length > 2 && args[2] instanceof Integer ? (int) args[2] : 0; if (args.length < 5) args = Arrays.copyOf(args, 5); oldObjectClass = (Class) args[4]; args[4] = arg.getClass();; - objArgs = preferedProtocol.serialize(arg); + Object[] objArgs = preferedProtocol.serialize(arg); StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, arg.getClass()) + (objArgs.length <= 0 ? "" : " ")); args = args.clone(); @@ -231,7 +226,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ args[4] = oldObjectClass; return index > 0 && objArgs.length > 0 ? sb.insert(0, '{').append('}') : sb; } - catch (Exception e) + catch (Exception e) { LogProvider.instance.logErr("Exception while serializing instance of \"" + arg.getClass().getName() + "\":", e); e.printStackTrace(); diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 2140bc2..f53382c 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -11,7 +11,7 @@ 1.3.7 SerialX devtools - Tools for debugging... + Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index a5ae395..2209204 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -177,9 +177,7 @@ public S LoadFrom(Reader reader, Object... formatArgs) @Override public A SerializeTo(A source, Object... args) throws IOException { - int tabs = 0; - if (args.length > 1 && args[1] instanceof Integer) - tabs = (int) args[1]; + int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; if (tabs == 0 && !(valuesCount() == 1 && variablesCount() <= 0 && get(0) instanceof Scope)) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index b5882bd..a71e0d3 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -90,14 +90,11 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. { if (obj != null && myHomeRegistry != null && obj.getClass().isArray()) { - int tabs = 0, index = 0; - if (args.length > 2 && args[2] instanceof Integer) - index = (int) args[2]; + int index = args.length > 2 && args[2] instanceof Integer ? (int) args[2] : 0; if (index <= 0 || myHomeRegistry.indexOf(OperationGroups.class) > -1) { - if (args.length > 1 && args[1] instanceof Integer) - tabs = (int) args[1]; + int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; if (args.length > 2) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index a322a66..e331296 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -132,11 +132,9 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. if (obj instanceof Entry) { Entry var = (Entry) obj; - int tabs = 0; - if (args.length > 1 && args[1] instanceof Integer) - tabs = (int) args[1]; + int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; - boolean jsonStyle = isJsonStyle(), genericVar = false; + boolean jsonStyle = isJsonStyle(), genericVar; Object key = (genericVar = !((key = var.getKey()) instanceof String)) ? myHomeRegistry.toString(key, args) : key, val = var.getValue(); return new StringBuilder().append(jsonStyle && !genericVar ? "\""+key+"\"" : key) .append(val instanceof GenericScope && !((GenericScope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")) From 22e0c60917e642e8866ac9240184666d4afaeace Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 12 Aug 2024 23:08:08 +0200 Subject: [PATCH 37/75] Doing static static member invocation the right way... fixing ObjConv is protocols expr bug, optimizing and improving, docs --- .../src/main/java/org/ugp/serialx/Utils.java | 159 ++++++++++-------- .../ugp/serialx/converters/DataConverter.java | 4 +- .../ugp/serialx/converters/DataParser.java | 2 +- .../serialx/converters/ProtocolConverter.java | 34 ++-- .../serialx/converters/VariableParser.java | 5 +- .../org/ugp/serialx/juss/JussSerializer.java | 70 ++++---- .../juss/converters/ObjectConverter.java | 16 +- .../juss/converters/OperationGroups.java | 72 ++++---- .../juss/converters/VariableConverter.java | 29 ++-- .../ConditionalAssignmentOperators.java | 12 +- 10 files changed, 194 insertions(+), 209 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 52e35b2..d6c455a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -181,8 +181,8 @@ public static Object InvokeFunc(Object obj, Class objCls, String name, Class< try { Method method = objCls.getMethod(name, argClasses); - Object resualt = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : resualt; + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) { @@ -190,8 +190,8 @@ public static Object InvokeFunc(Object obj, Class objCls, String name, Class< if (method.getName().equals(name)) try { - Object resualt = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : resualt; + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; } catch (IllegalArgumentException e) {} @@ -224,8 +224,8 @@ public static T Clone(T obj) /** * @param obj | Object to clone. * @param parsersToUse | Parsers that will be used for cloning... - * @param converterArgs | Argument for {@link DataConverter#objToString(Registry, Object, Object...)}! - * @param parserArgs | Arguments for {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)}! + * @param converterArgs | Argument for {@link DataConverter#objToString(Object, Object...)}! + * @param parserArgs | Arguments for {@link ParserRegistry#parse(String, boolean, Class, Object...)}! * * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
@@ -534,18 +534,21 @@ public static String[] splitValues(String s, int i, int limit, int splittingStra List result = new ArrayList<>(); - int brackets = 0, quote = 0, lastIndex = 0, len = s.length(); + int brackets = 0, lastIndex = 0, len = s.length(); for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) { char ch = s.charAt(i); if (ch == '"') - quote++; - - if (quote % 2 == 0) + { + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + while (s.charAt(i) != '"'); + } + else { if (isOneOf(ch, splitBreaks)) { - brackets = quote = 0; + brackets = 0; break; } @@ -576,13 +579,8 @@ else if ((ch | ' ') == '}') if (brackets > 0) throw new IllegalArgumentException("Unclosed brackets in: " + s); - else if (quote % 2 != 0) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); - else - { - result.add(s.substring(lastIndex, len).trim()); - } - + + result.add(s.substring(lastIndex, len).trim()); return result.toArray(new String[0]); } @@ -609,33 +607,29 @@ public static int indexOfNotInObj(CharSequence s, char... oneOf) * * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! * - * @since 1.3.5 + * @since 1.3.5 (expanded in 1.3.8) */ public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) { - for (int brackets = 0, quote = 0; from < to; from++) + for (int brackets = 0; from < to; from++) { char ch = s.charAt(from); if (ch == '"') - quote++; - - if (quote % 2 == 0) + while (++from < to && s.charAt(from) != '"'); + else if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) { - if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) - { - if (firstIndex) - return from; - defaultReturn = from; - } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); - } + if (firstIndex) + return from; + defaultReturn = from; + } + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); } } return defaultReturn; @@ -643,64 +637,71 @@ else if ((ch | ' ') == '}') /** * @param s | CharSequence to search! - * @param sequenceToFind | CharSequence to find! + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! * * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! * * @since 1.3.0 */ - public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind) + public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) { - return indexOfNotInObj(s, sequenceToFind, true); + return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); } /** * @param s | CharSequence to search! - * @param sequenceToFind | CharSequence to find! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be s.length()). + * @param defaultReturn | Index to return by default (usually -1). * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! * * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! * - * @since 1.3.5 + * @since 1.3.5 (expanded in 1.3.8) */ - public static int indexOfNotInObj(CharSequence s, CharSequence sequenceToFind, boolean firstIndex) + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) { - int len = s.length(), lenToFind = sequenceToFind.length(); - if (len < lenToFind) - return -1; - int found = -1; - for (int i = 0, brackets = 0, quote = 0, match = 0; i < len; i++) + if (sequencesToFind.length < 1) + return defaultReturn; + + for (int brackets = 0; from < to; from++) { - char ch = s.charAt(i); + char ch = s.charAt(from); if (ch == '"') - quote++; - - if (quote % 2 == 0) + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') { - if (brackets == 0 && ch == sequenceToFind.charAt(match++)) + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing closing bracket in: " + s); + } + else if (brackets == 0) + { + findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) { - if (match == lenToFind) + CharSequence currentMatch; + if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) { - found = i - match + 1; - if (firstIndex) - return found; - match = 0; + int match = 1, lenToFind = currentMatch.length(); + for (int i = from+1; i < to && match < lenToFind; i++, match++) + if (s.charAt(i) != currentMatch.charAt(match)) + continue findMatch; + + if (match == lenToFind) + { + defaultReturn = from; + if (firstIndex) + return defaultReturn; + } } } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); - } - else - match = 0; } } - return found; + return defaultReturn; } /** @@ -798,14 +799,26 @@ public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOt * @param str | String to display! * @param pos | Position to display! * - * @return String with displayed position by using »! + * @return String with displayed position by using » or ^ under it! * Use for debugging or error printing! * * @since 1.3.2 */ public static String showPosInString(CharSequence str, int pos) { - return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); + if (pos < 0) + return str.toString(); + + try + { + if (contains(str, '\n', '\r')) + return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); + return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); + } + catch (IndexOutOfBoundsException e) + { + return str.toString(); + } } /* Arrays */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 6c11480..71bc6e2 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -1,7 +1,5 @@ package org.ugp.serialx.converters; -import org.ugp.serialx.Registry; - /** * This is DataParser with extended functionality! {@link DataConverter} can also parse data like DataParser but is also capable of converting them back to string! * This to string convertation is performed by {@link DataConverter#toString(Object)} and result of this convertation supposed to be parsable by {@link DataConverter#parse(String, Object...)} meaning one converter supposed to be parsing and converting via the same string format! @@ -15,7 +13,7 @@ public interface DataConverter extends DataParser { /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param obj | Object to convert into string! * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 2b7ac42..d9d1509 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -44,7 +44,7 @@ public interface DataParser public static final ParserRegistry REGISTRY = new ParserRegistry(new VariableParser(), new StringConverter(), new ProtocolConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param str | Source string, preferably trimed! * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index a5a5a3c..033879a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -9,10 +9,11 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; +import java.util.HashSet; +import java.util.Set; import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.Utils; @@ -70,17 +71,17 @@ public class ProtocolConverter implements DataConverter */ protected boolean useBase64IfCan = false; - protected boolean allowStaticMemberInvocation = false; + protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, Scope.class, Double.class, Float.class, String.class)); @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) { - int len; + int len; if ((len = str.length()) > 0) { if ((str.charAt(0) | ' ') == '{' && (str.charAt(--len) | ' ') == '}') // Unwrap if wrapped in {} str = str.substring(1, len).trim(); - + Class objClass; if ((objClass = getProtocolExprClass(str, compilerArgs)) != null) // Get class of protocol expr or continue if there is none return parse(myHomeRegistry, objClass, str, compilerArgs); @@ -117,9 +118,9 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String if ((args[0].charAt(0) | ' ') != '{' && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation { String memberName = args[0].substring(nameIndex + 2); - if (!isAllowStaticMemberInvocation()) + if (!getInvokableClasses().contains(objClass)) { - LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because this feature is disabled by default for security reasons!", null); + LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because it was not enabled for this class for security reasons!", null); return null; } @@ -169,7 +170,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object.. } /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param obj | Object to convert into string! * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! @@ -277,23 +278,14 @@ public void setUseBase64IfCan(boolean useBase64IfCan) } /** - * @return True if invocation of static members (:: operator) is allowed (false by default)! - * - * @since 1.3.8 - */ - public boolean isAllowStaticMemberInvocation() - { - return allowStaticMemberInvocation; - } - - /** - * @param allowStaticMemberInvocation | Enable/disable the invocation of static members (:: operator) (false by default)! + * @return Classes that are eligible for public static member invocation (:: operator)!
+ * Note: {@link Math} {@link Scope} {@link Double}, {@link Float} and {@link String} are invokable by default! If you want to disable static member invocation completely, call {@link Set#clear()} on this method! * - * @since 1.3.8 + * @since 1.3.8 */ - public void setAllowStaticMemberInvocation(boolean allowStaticMemberInvocation) + public Set> getInvokableClasses() { - this.allowStaticMemberInvocation = allowStaticMemberInvocation; + return invokableClasses; } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 0f9af02..1734435 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -5,7 +5,6 @@ import static org.ugp.serialx.Utils.splitValues; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; @@ -51,7 +50,7 @@ public Object getMemberOperator(Object source, Object member) } /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param str | Source string, should not be null or empty (preferably with some variables to read)! * @param scope | Source scope to read from, can't be null! * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. @@ -112,4 +111,4 @@ else if (newModif = str.endsWith("::new")) return CONTINUE; } -} +} \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index ce5faab..f857eeb 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -569,7 +569,7 @@ else if (ch == '}' || ch == ']') sb.append(ch); } } - sb.append(lastNotBlank == '}' || lastNotBlank == ']' ? ';' : ' '); + sb.append((lastNotBlank | ' ') == '}' ? ';' : ' '); } else sb.append(line).append('\n'); @@ -596,57 +596,49 @@ protected List splitAndParse(StringBuilder formattedStr, Object... parse ParserRegistry reg = getParsers(); //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; - int brackets = 0, quote = 0, lastIndex = 0, len = formattedStr.length(); + int brackets = 0, lastIndex = 0, len = formattedStr.length(); //boolean isBracketSplit = false; for (int i = 0; i < len; i++) { char ch = formattedStr.charAt(i); if (ch == '"') - quote++; - - if (quote % 2 == 0) { - /*if (isBracketSplit) - add = 0; - isBracketSplit = false;*/ - if (brackets == 0 && (ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) - { - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); - if (!str.isEmpty()) - { - Object obj = parseObject(reg, str, parserArgs); - if (obj != VOID) - result.add(obj); - } - //add = 1; - } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); + while (formattedStr.charAt(i) != '"'); + } + else if (brackets == 0 && (ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) + { + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); + if (!str.isEmpty()) { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + formattedStr); + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); } + //add = 1; } - } - - if (quote % 2 != 0) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); - else if (brackets > 0) - throw new IllegalArgumentException("Unclosed brackets in: " + formattedStr); - else - { - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); - if (!str.isEmpty()) + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') { - Object obj = parseObject(reg, str, parserArgs); - if (obj != VOID) - result.add(obj); + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + formattedStr); } } + if (brackets > 0) + throw new IllegalArgumentException("Unclosed brackets in: " + formattedStr); + + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); + if (!str.isEmpty()) + { + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); + } return result; } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 086ac55..e666a2d 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -9,7 +9,6 @@ import java.util.Base64; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataParser; @@ -79,16 +78,19 @@ public class ObjectConverter extends ProtocolConverter @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) { - int len; + int len; if ((len = str.length()) > 0) { - boolean hasOp, hasCls = false; - if ((hasOp = (str.charAt(0) | ' ') == '{') && (hasCls = (str.charAt(--len) | ' ') == '}')) // Unwrap if wrapped in {} - len = (str = str.substring(1, len).trim()).length(); + boolean hasOp, hasCls; + if ((hasOp = (str.charAt(0) | ' ') == '{') && (hasCls = (str.charAt(len-1) | ' ') == '}')) // Unwrap if wrapped in {} + len = (str = str.substring(1, --len).trim()).length(); + else + hasCls = false; Class objClass; int chI; - if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) < 0 || (++chI < len && str.charAt(chI) == ':')) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) // Is protocol expr +// if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || indexOfNotInObj(str, chI, len, -1, true, "==", "::") != -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) + if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || ++chI < len && str.charAt(chI) == ':' && indexOfNotInObj(str, ++chI, len, -1, true, ';', ',', '=') == -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) // Is protocol expr in disguise (I know I know but come up with something better before judging...) return parse(myHomeRegistry, objClass, str, compilerArgs); if (hasOp && hasCls) //Is scope @@ -126,7 +128,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object.. } /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parseObj(Registry, String, boolean, Class[], Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param obj | Object to convert into string! * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 56f4331..f0d4cce 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -23,7 +23,7 @@ * * @since 1.3.0 */ -public class OperationGroups implements DataParser +public class OperationGroups implements DataParser { /** * @deprecated (since 1.3.8) DO NOT USE, USE {@link OperationGroups#groupMark} instead!
@@ -127,26 +127,22 @@ public static int isGroupMark(CharSequence s, char groupMark) */ public static int indexOfOpening(CharSequence str, int from, char... openings) { - for (int len = str.length(), quote = 0, brackets = 0; from < len; from++) + for (int len = str.length(), brackets = 0; from < len; from++) { char ch = str.charAt(from); - - if (ch == '\"') - quote++; - else if (quote % 2 == 0) + if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') { - if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + str); - } - else if (brackets == 0 && isOneOf(ch, openings)) - return from; + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + str); } + else if (brackets == 0 && isOneOf(ch, openings)) + return from; } return -1; } @@ -163,33 +159,29 @@ else if (brackets == 0 && isOneOf(ch, openings)) */ public static int indexOfClosing(CharSequence str, int from, char[] openings, char... closing) { - for (int len = str.length(), quote = 0, brackets = 0, ops = 0; from < len; from++) + for (int len = str.length(), brackets = 0, ops = 0; from < len; from++) { char ch = str.charAt(from); - - if (ch == '\"') - quote++; - else if (quote % 2 == 0) + if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') { - if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + str); - } - else if (brackets == 0) + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + str); + } + else if (brackets == 0) + { + if (isOneOf(ch, openings)) + ops++; + else if (isOneOf(ch, closing)) { - if (isOneOf(ch, openings)) - ops++; - else if (isOneOf(ch, closing)) - { - if (ops == 1) - return from; - ops--; - } + if (ops == 1) + return from; + ops--; } } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index e331296..0f00452 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -204,24 +204,21 @@ public void setJsonStyle(boolean jsonStyle) */ public static int isVarAssignment(CharSequence s) { - for (int i = 0, brackets = 0, quote = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) + for (int i = 0, brackets = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) { char ch = s.charAt(i); if (ch == '"') - quote++; - - if (quote % 2 == 0) - { - if (ch == '?') - return -1; - else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) - return i; - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - if (brackets > 0) - brackets--; - } + while (++i < len && s.charAt(i) != '"'); + else if (ch == '?') + return -1; + else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) + return i; + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') + if (brackets > 0) + brackets--; + oldCh = ch; } return -1; @@ -248,4 +245,4 @@ public static Entry NewVariable(String varName, T varValue) { return new AbstractMap.SimpleImmutableEntry<>(varName, varValue); } -} +} \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index e3ad5cf..768f863 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -66,16 +66,16 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) */ public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) { - for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, quote = 0, brackets = 0; i < len; i++) + for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, brackets = 0; i < len; i++) { char ch = str.charAt(i); if (ch == '\"') - quote++; + while (++i < len && str.charAt(i) != '"'); else if ((ch | ' ') == '{') brackets++; else if ((ch | ' ') == '}') brackets--; - else if (quote % 2 == 0 && brackets == 0) + else if (brackets == 0) { for (char token : ternaryOperators) if (ch == token && oldCh != token && (i >= len-1 || str.charAt(i+1) != token)) @@ -103,16 +103,16 @@ else if (quote % 2 == 0 && brackets == 0) */ public static int indexOfOne(CharSequence str, int from, char oneChar) { - for (int len = str.length(), oldCh = -1, quote = 0, brackets = 0; from < len; from++) + for (int len = str.length(), oldCh = -1, brackets = 0; from < len; from++) { char ch = str.charAt(from); if (ch == '\"') - quote++; + while (++from < len && str.charAt(from) != '"'); else if ((ch | ' ') == '{') brackets++; else if ((ch | ' ') == '}') brackets--; - else if (quote % 2 == 0 && brackets == 0 && ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) + else if (brackets == 0 && ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) return from; oldCh = ch; } From df5babeaf6c29193c332c5d0f277bfd7c029d285 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 14 Aug 2024 00:44:36 +0200 Subject: [PATCH 38/75] small perfromacne improve for string analyse utils, finilizing mvn 1.3.8 --- SerialX-core/pom.xml | 2 +- .../src/main/java/org/ugp/serialx/Utils.java | 120 ++++++++++-------- SerialX-devtools/pom.xml | 2 +- SerialX-json/pom.xml | 2 +- SerialX-juss/pom.xml | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 32 ++--- .../juss/converters/OperationGroups.java | 46 ++++--- .../juss/converters/VariableConverter.java | 25 ++-- SerialX-operators/pom.xml | 2 +- .../operators/ArithmeticOperators.java | 42 +++--- .../ConditionalAssignmentOperators.java | 44 +++++-- pom.xml | 9 +- 12 files changed, 193 insertions(+), 135 deletions(-) diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index fec3b0e..1d7592f 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -8,7 +8,7 @@ org.ugp.serialx core - 1.3.7 + 1.3.8 SerialX core Core of SerialX. Contains core features and utilities shared across the library. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index d6c455a..3b9f370 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -466,7 +466,8 @@ public static StringBuilder multilpy(CharSequence str, int times) * @param s | String to split and check some syntax. * @param splitter | Chars where string will be split! * - * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med! + * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} * * @since 1.0.0 */ @@ -483,7 +484,8 @@ public static String[] splitValues(String s, char... splitter) * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! * @param splitter | Chars where string will be split! * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' * * @since 1.3.0 */ @@ -501,7 +503,8 @@ public static String[] splitValues(String s, int limit, int splittingStrategy, c * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! * @param splitter | Chars where string will be split! * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' * * @since 1.3.5 */ @@ -517,10 +520,11 @@ public static String[] splitValues(String s, int limit, int splittingStrategy, c * @param splittingStrategy | If 0, splitting will occur after each splitter! * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! * @param splitter | Chars where string will be split! * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med! + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' * * @since 1.3.8 */ @@ -534,51 +538,47 @@ public static String[] splitValues(String s, int i, int limit, int splittingStra List result = new ArrayList<>(); - int brackets = 0, lastIndex = 0, len = s.length(); + int lastIndex = 0, len = s.length(); for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) { - char ch = s.charAt(i); + int ch = s.charAt(i); if (ch == '"') { do if (++i >= len) throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); while (s.charAt(i) != '"'); } - else + else if ((ch | ' ') == '{') { - if (isOneOf(ch, splitBreaks)) + for (int brackets = 1; brackets != 0; ) { - brackets = 0; - break; - } - - if (brackets == 0 && isOneOf(ch, splitter) && - (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) - { - String tok = s.substring(lastIndex, i).trim(); - if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) - { - result.add(tok); - lastIndex = i + 1; - - count++; - } + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') + } + else if (isOneOf(ch, splitBreaks)) + break; + else if (isOneOf(ch, splitter) && + (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + String tok = s.substring(lastIndex, i).trim(); + if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + s); + result.add(tok); + lastIndex = i + 1; + + count++; } } + oldCh = ch; } - - if (brackets > 0) - throw new IllegalArgumentException("Unclosed brackets in: " + s); result.add(s.substring(lastIndex, len).trim()); return result.toArray(new String[0]); @@ -611,26 +611,31 @@ public static int indexOfNotInObj(CharSequence s, char... oneOf) */ public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) { - for (int brackets = 0; from < to; from++) + for (; from < to; from++) { - char ch = s.charAt(from); + int ch = s.charAt(from); if (ch == '"') while (++from < to && s.charAt(from) != '"'); - else if (brackets == 0 && /*oneOf.length == 0 ? ch == oneOf[0] :*/ isOneOf(ch, oneOf)) + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else if (isOneOf(ch, oneOf)) { if (firstIndex) return from; defaultReturn = from; } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); - } } return defaultReturn; } @@ -665,21 +670,26 @@ public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultR if (sequencesToFind.length < 1) return defaultReturn; - for (int brackets = 0; from < to; from++) + for (; from < to; from++) { - char ch = s.charAt(from); + int ch = s.charAt(from); if (ch == '"') while (++from < to && s.charAt(from) != '"'); else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing closing bracket in: " + s); + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } } - else if (brackets == 0) + else { findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) { diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index f53382c..62408a9 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -8,7 +8,7 @@ org.ugp.serialx devtools - 1.3.7 + 1.3.8 SerialX devtools Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 3477e6c..099d015 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -8,7 +8,7 @@ org.ugp.serialx json - 1.3.7 + 1.3.8 SerialX json SerialX Json support diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index 2c451bd..a37638a 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -8,7 +8,7 @@ org.ugp.serialx juss - 1.3.7 + 1.3.8 SerialX-juss SerialX support for Java Universal Serial Script data format, custom default format of SerialX! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index f857eeb..16d8cbe 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -596,18 +596,32 @@ protected List splitAndParse(StringBuilder formattedStr, Object... parse ParserRegistry reg = getParsers(); //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; - int brackets = 0, lastIndex = 0, len = formattedStr.length(); + int lastIndex = 0, len = formattedStr.length(); //boolean isBracketSplit = false; for (int i = 0; i < len; i++) { - char ch = formattedStr.charAt(i); + int ch = formattedStr.charAt(i); if (ch == '"') { do if (++i >= len) throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); while (formattedStr.charAt(i) != '"'); } - else if (brackets == 0 && (ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + formattedStr); + if ((ch = (formattedStr.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && formattedStr.charAt(i) != '"'); + } + } + else if ((ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) { String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); if (!str.isEmpty()) @@ -618,20 +632,8 @@ protected List splitAndParse(StringBuilder formattedStr, Object... parse } //add = 1; } - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + formattedStr); - } } - if (brackets > 0) - throw new IllegalArgumentException("Unclosed brackets in: " + formattedStr); - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); if (!str.isEmpty()) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index f0d4cce..9a95205 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -127,21 +127,26 @@ public static int isGroupMark(CharSequence s, char groupMark) */ public static int indexOfOpening(CharSequence str, int from, char... openings) { - for (int len = str.length(), brackets = 0; from < len; from++) + for (int len = str.length(); from < len; from++) { - char ch = str.charAt(from); + int ch = str.charAt(from); if (ch == '"') while (++from < len && str.charAt(from) != '"'); else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + str); + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } } - else if (brackets == 0 && isOneOf(ch, openings)) + else if (isOneOf(ch, openings)) return from; } return -1; @@ -159,21 +164,26 @@ else if (brackets == 0 && isOneOf(ch, openings)) */ public static int indexOfClosing(CharSequence str, int from, char[] openings, char... closing) { - for (int len = str.length(), brackets = 0, ops = 0; from < len; from++) + for (int len = str.length(), ops = 0; from < len; from++) { - char ch = str.charAt(from); + int ch = str.charAt(from); if (ch == '"') while (++from < len && str.charAt(from) != '"'); else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + str); + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } } - else if (brackets == 0) + else { if (isOneOf(ch, openings)) ops++; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 0f00452..dbeaf18 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -204,20 +204,29 @@ public void setJsonStyle(boolean jsonStyle) */ public static int isVarAssignment(CharSequence s) { - for (int i = 0, brackets = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) + for (int i = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) { - char ch = s.charAt(i); + int ch = s.charAt(i); if (ch == '"') while (++i < len && s.charAt(i) != '"'); else if (ch == '?') return -1; - else if (brackets == 0 && (ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) - return i; else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - if (brackets > 0) - brackets--; + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + } + } + else if ((ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) + return i; oldCh = ch; } diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index f27574e..cf840c6 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -8,7 +8,7 @@ org.ugp.serialx operators - 1.3.7 + 1.3.8 SerialX operators This modul contains basic operators contained in almost every programing language... diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 8508845..e888b44 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -414,8 +414,7 @@ else if ((ch | ' ') == '{') brackets++; else if ((ch | ' ') == '}') brackets--; - - if (type == 1 || quote % 2 == 0 && brackets == 0) + else if (type == 1 || quote % 2 == 0 && brackets == 0) { if ((type = isOneOf(ch, oprs) ? 1 : 0) != lastType) { @@ -450,29 +449,36 @@ else if ((ch | ' ') == '}') public static boolean isExpression(CharSequence str, int to, char... operators) { int hasOpr = -1; - for (int i = 0, oldCh = 0, isCof = 0, quote = 0, brackets = 0; i < to; i++) + for (int i = 0, oldCh = 0, isCof = 0; i < to; i++) { - char ch = str.charAt(i); + int ch = str.charAt(i); if (ch > 32) { - if (ch == '\"') - quote++; - else if (quote % 2 == 0) + if (ch == '"') + while (++i < to && str.charAt(i) != '"'); + else if ((ch | ' ') == '{') { - if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - brackets--; - else if (brackets == 0) + for (int brackets = 1; brackets != 0; ) { - if (isOneOf(ch, operators)) - hasOpr = isCof = 0; - else if (oldCh <= 32 && isCof == 1) - return false; - else - isCof = 1; + if (++i >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < to && str.charAt(i) != '"'); } } + else + { + if (isOneOf(ch, operators)) + hasOpr = isCof = 0; + else if (oldCh <= 32 && isCof == 1) + return false; + else + isCof = 1; + } } oldCh = ch; } diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 768f863..0b2a761 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -66,16 +66,26 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) */ public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) { - for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0, brackets = 0; i < len; i++) + for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0; i < len; i++) { - char ch = str.charAt(i); + int ch = str.charAt(i); if (ch == '\"') while (++i < len && str.charAt(i) != '"'); else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - brackets--; - else if (brackets == 0) + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && str.charAt(i) != '"'); + } + } + else { for (char token : ternaryOperators) if (ch == token && oldCh != token && (i >= len-1 || str.charAt(i+1) != token)) @@ -103,16 +113,26 @@ else if (brackets == 0) */ public static int indexOfOne(CharSequence str, int from, char oneChar) { - for (int len = str.length(), oldCh = -1, brackets = 0; from < len; from++) + for (int len = str.length(), oldCh = -1; from < len; from++) { - char ch = str.charAt(from); + int ch = str.charAt(from); if (ch == '\"') while (++from < len && str.charAt(from) != '"'); else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - brackets--; - else if (brackets == 0 && ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } + } + else if (ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) return from; oldCh = ch; } diff --git a/pom.xml b/pom.xml index de6c8cc..1068d9c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ SerialX root Store Java objects into file via SerialX. SerialX is a powerful utility library to serialize objects in Java programmatically via recursive descent parser for custom domain-specific languages! https://github.com/SimplyProgrammer/Java-SerialX + 2020 @@ -42,7 +43,7 @@ 8 - 1.3.7 + 1.3.8 UTF-8 ${java.version} @@ -68,12 +69,12 @@ org.codehaus.plexus plexus-compiler-eclipse - 2.8.8 + 2.9.0 - + org.eclipse.jdt ecj - 3.33.0 + 3.25.0 From 6206993f70629e3eef433e602e28fc180a8c96c9 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 14 Aug 2024 19:59:28 +0200 Subject: [PATCH 39/75] fixing broken jdocs links, adding source generator and jdoc generator --- .../src/main/java/org/ugp/serialx/Scope.java | 4 +-- .../src/main/java/org/ugp/serialx/Utils.java | 8 ++--- .../serialx/converters/ProtocolConverter.java | 20 +++++------ .../converters/imports/ImportsProvider.java | 2 +- .../devtools/SerializationDebugger.java | 2 +- .../org/ugp/serialx/json/JsonSerializer.java | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 14 ++++---- .../juss/converters/ObjectConverter.java | 16 ++++----- .../operators/ArithmeticOperators.java | 2 +- .../ConditionalAssignmentOperators.java | 2 +- pom.xml | 34 ++++++++++++++++++- 11 files changed, 69 insertions(+), 37 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index 00e7652..ca2f71c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -93,7 +93,7 @@ public Scope(GenericScope sourceScope) /** * @param variablesMap | Initial variables to be added in to this scope! * @param values | Initial independent values to be added in to this scope! - * @param | Parent of this scope. + * @param parent | Parent of this scope. * @since 1.3.5 */ @@ -103,7 +103,7 @@ public Scope(Map variablesMap, Collection values, GenericScope objCls, String name, Object /** * @param obj | The object the underlying method is invoked from! - * @param cls | Class to invoke method from. + * @param objCls | Class to invoke method from. * @param name | Name of public static method to be called. * @param argClasses | Classes of args. * @param args | Arguments of method. Arguments should be certain if method is overloaded! @@ -447,8 +447,8 @@ public static StringBuilder multilpy(char ch, int times) } /** - * @param ch | String to multiply! - * @param str | Count of multiplication! + * @param str | String to multiply! + * @param times | Count of multiplication! * * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 033879a..2c7e923 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -164,9 +164,9 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { - return toString(myHomeRegistry, arg, null, args); + return toString(myHomeRegistry, obj, null, args); } /** @@ -181,15 +181,15 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object.. * @since 1.3.5 */ @SuppressWarnings("unchecked") - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { - if (arg == null) + if (obj == null) return CONTINUE; - if (useBase64IfCan && arg instanceof Serializable) + if (useBase64IfCan && obj instanceof Serializable) return CONTINUE; - if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args)) != null) + if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE, args)) != null) { Class oldObjectClass = null; try @@ -200,10 +200,10 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ if (args.length < 5) args = Arrays.copyOf(args, 5); oldObjectClass = (Class) args[4]; - args[4] = arg.getClass();; + args[4] = obj.getClass();; - Object[] objArgs = preferedProtocol.serialize(arg); - StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, arg.getClass()) + (objArgs.length <= 0 ? "" : " ")); + Object[] objArgs = preferedProtocol.serialize(obj); + StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, obj.getClass()) + (objArgs.length <= 0 ? "" : " ")); args = args.clone(); for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) @@ -229,7 +229,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Serializ } catch (Exception e) { - LogProvider.instance.logErr("Exception while serializing instance of \"" + arg.getClass().getName() + "\":", e); + LogProvider.instance.logErr("Exception while serializing instance of \"" + obj.getClass().getName() + "\":", e); e.printStackTrace(); } args[4] = oldObjectClass; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java index 835bcc7..968d64a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -196,7 +196,7 @@ public Imports(Collection c) /** * Constructs an {@link Imports} with inserted imports. * - * @param parsers | Initial content of registry. + * @param imports | Initial content of registry. * * @since 1.3.5 */ diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index 7a7a970..1c36d7b 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -169,7 +169,7 @@ public static T debug(T serializer) /** * @param serializer | Serializer to debug! - * @param debuger | Specific debugger to use! + * @param debugger | Specific debugger to use! * * @return Serializer capable of debugging its serialization and deserialization! * diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 2209204..c3f2d74 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -229,7 +229,7 @@ public A SerializeAsSubscope(A source, Object... args) th } /** - * @param jsonSerializer | JsonSerializer to create {@link JussSerializer} from! + * @param jussSerializer | JussSerializer to create {@link JsonSerializer} from! * * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! * diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 16d8cbe..cb77270 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -388,7 +388,7 @@ public Appendable GenerateComment(Appendable source, ParserRegistry registry, Ob /** * @param reader | Reader to read from! - * @param formatingArgs | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this scope (it can be also boolean signifying if formating is required), 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, and additional argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}). + * @param args | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this scope (it can be also boolean signifying if formating is required), 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, and additional argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}). * * @return This scope after loading data from reader (you most likely want to return "this")! * @@ -673,7 +673,7 @@ protected Object parseObject(ParserRegistry registry, String str, Object... pars } /** - * @param variable | Variable to clone! + * @param variableKey | Variable to clone! * * @return Clone of value stored by variable with inserted name or null if there is no such a one! *

@@ -681,13 +681,13 @@ protected Object parseObject(ParserRegistry registry, String str, Object... pars * * @since 1.3.2 */ - public T cloneOf(String variableName) + public T cloneOf(String variableKey) { - return cloneOf(variableName, null); + return cloneOf(variableKey, null); } /** - * @param variable | Variable to clone! + * @param variableKey | Variable to clone! * @param defaultValue | Default value to return. * * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! @@ -696,9 +696,9 @@ public T cloneOf(String variableName) * * @since 1.3.2 */ - public T cloneOf(String variableName, T defaultValue) + public T cloneOf(String variableKey, T defaultValue) { - T obj = get(variableName, defaultValue); + T obj = get(variableKey, defaultValue); if (obj == defaultValue) return defaultValue; return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index e666a2d..52e14c9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -122,9 +122,9 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { - return toString(myHomeRegistry, arg, null, args); + return toString(myHomeRegistry, obj, null, args); } /** @@ -139,17 +139,17 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object.. * @since 1.3.5 */ @SuppressWarnings("unchecked") - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, SerializationProtocol preferedProtocol, Object... args) + public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { - if (arg instanceof Scope) + if (obj instanceof Scope) { Serializer serializer; try { - if (arg instanceof Serializer) - serializer = (Serializer) arg; + if (obj instanceof Serializer) + serializer = (Serializer) obj; else if (args.length > 0 && args[0] instanceof Serializer) - (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) arg); + (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) obj); else serializer = getPreferredSerializer(); } @@ -182,7 +182,7 @@ else if (args.length > 0 && args[0] instanceof Serializer) } } - return super.toString(myHomeRegistry, arg, preferedProtocol, args); + return super.toString(myHomeRegistry, obj, preferedProtocol, args); } @Override diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index e888b44..55b3039 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -23,7 +23,7 @@ public class ArithmeticOperators implements DataParser { /** - * @deprecated DO NOT USE! USE {@link ArithmeticOperators#evalOperator(Object, String, Object)} AND {@link ArithmeticOperators#getOperatorPriority(String)} INSTEAD! + * @deprecated DO NOT USE! USE {@link ArithmeticOperators#operator(Object, String, Object)} AND {@link ArithmeticOperators#getOperatorPriority(String)} INSTEAD! */ @Deprecated protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"}; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 0b2a761..a86a22c 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -58,7 +58,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) /** * @param str | Source string to search. * @param defaultCountOfConfitions | How many condition operators (tenraryTokens[0]) are expected. Should be 1 in most cases. - * @param tenraryTokens | Characters representing parts of ternary operator. Index 0 should be '?' and index 1 should be ':'. + * @param ternaryOperators | Characters representing parts of ternary operator. Index 0 should be '?' and index 1 should be ':'. * * @return Return index of else branch in ternary operator expression or -1 if there is no else branch! * diff --git a/pom.xml b/pom.xml index 1068d9c..85b0b8a 100644 --- a/pom.xml +++ b/pom.xml @@ -48,10 +48,12 @@ UTF-8 ${java.version} ${java.version} + + serialx-${project.artifactId}-${project.version} - serialx-${project.artifactId}-${project.version} + ${project.build.finalName} @@ -78,6 +80,36 @@ + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.3 + + + -Xdoclint:none + -Xdoclint:none + + + + + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + + jar + + + + \ No newline at end of file From c57aececd4147e58b58aea225d8cf7995cdbb74e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 16 Aug 2024 22:28:01 +0200 Subject: [PATCH 40/75] fixing jdocs --- .../main/java/org/ugp/serialx/GenericScope.java | 2 +- .../src/main/java/org/ugp/serialx/Scope.java | 8 ++++---- .../src/main/java/org/ugp/serialx/Serializer.java | 12 ++++++------ .../src/main/java/org/ugp/serialx/Utils.java | 14 +++++++------- .../org/ugp/serialx/converters/VariableParser.java | 2 +- .../java/org/ugp/serialx/json/JsonSerializer.java | 14 +++++++------- .../java/org/ugp/serialx/juss/JussSerializer.java | 14 +++++++------- .../serialx/juss/converters/VariableConverter.java | 2 +- .../ugp/serialx/juss/protocols/AutoProtocol.java | 9 ++++----- .../converters/operators/ComparisonOperators.java | 6 +++--- pom.xml | 2 +- 11 files changed, 42 insertions(+), 43 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index a47d582..5e9cdb9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -553,7 +553,7 @@ public GenericScope getGenericScope(K... pathToScope) /** * @param type | Class of object to create (may or may not support other implementations of {@link Type}). * - * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in {@link Serializer#PROTOCOL_REGISTRY}! + * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in {@link SerializationProtocol#REGISTRY}! * * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index ca2f71c..af25e9a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -702,7 +702,7 @@ public Scope getScope(String... pathToScope) * If independent value is {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. * Note: Scopes are searched via regular independent value index no scope index like {@link Scope#getScope(int)}. * - * @see Serializer#PROTOCOL_REGISTRY + * @see SerializationProtocol#REGISTRY * @see GenericScope#toObject(Class) * * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! @@ -725,7 +725,7 @@ public T toObjectOf(int scopesValueIndex, Class objClass) throws Exceptio * @return Value of variable with name or null if there is no such a one! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. * - * @see Serializer#PROTOCOL_REGISTRY + * @see SerializationProtocol#REGISTRY * @see GenericScope#toObject(Class) * * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! @@ -745,7 +745,7 @@ public T toObjectOf(String variableWithscope, Class objClass) throws Exce * @return Value of variable with name or defaultValue if there is no such a one or given key contains null! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. * - * @see Serializer#PROTOCOL_REGISTRY + * @see SerializationProtocol#REGISTRY * @see GenericScope#toObject(Class) * * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! @@ -766,7 +766,7 @@ public T toObjectOf(String variableWithscope, Class objClass, T defaultVa * @return Value of variable with name or defaultValue if there is no such a one or given key contains null! If there is no Scope stored by variableWithScope this function behaves same as {@link Scope#get(String, Object)}! * If variableWithScope contains {@link GenericScope} like it supposed to, then values of scope are parsed to {@link SerializationProtocol} of objClass. * - * @see Serializer#PROTOCOL_REGISTRY + * @see SerializationProtocol#REGISTRY * @see GenericScope#toObject(Class) * * @throws Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 95fd1d3..72d167a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -651,11 +651,11 @@ public T getParsed(String variableWithStringValue, Object... args) {@link Appendable} - {@link Serializer#SerializeTo(Appendable)} + {@link Serializer#SerializeTo(Appendable, Object...)} {@link OutputStream} - {@link Serializer#SerializeTo(OutputStream)} + {@link Serializer#SerializeTo(OutputStream, Object...)} {@link URL} @@ -755,7 +755,7 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN /** * @param newInstance | New instance of specific {@link Serializer} * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! * * @return {@link Serializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

* Table of specific Object --> Serializer conversions: @@ -772,7 +772,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence)} + {@link Serializer#LoadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -780,7 +780,7 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File)} + {@link Serializer#LoadFrom(File, Object...)} {@link Reader} @@ -788,7 +788,7 @@ Obtained serializer content (return) {@link InputStream} - {@link Serializer#LoadFrom(InputStream)} + {@link Serializer#LoadFrom(InputStream, Object...)} {@link URL} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 674a38d..37b2d5b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -51,7 +51,7 @@ public static String LoadFileToString(File f) throws IOException /** * @param f | Source file. * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! * * @return Content of file as string. * @throws IOException @@ -66,7 +66,7 @@ public static String LoadFileToString(File f, int endlMode) throws IOException /** * @param input | Input stream to read to string! * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! * * @return Reader converted to string form! * @@ -82,7 +82,7 @@ public static String StreamToString(InputStream input, int endlMode) throws IOEx /** * @param input | Input reader! * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link Serializer#LoadFileToString(File)} which is doing this automatically! + * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! * * @return Reader converted to string form! * @@ -113,7 +113,7 @@ public static String StreamToString(Reader input, int endlMode) throws IOExcepti * @param name | Name of public static method to be called. * @param args | Arguments of method. Arguments should be certain if method is overloaded! * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. * * @throws InvocationTargetException if called method throws and exception while calling! * @@ -129,7 +129,7 @@ public static Object InvokeStaticFunc(Class cls, String name, Object... args) * @param name | Name of public static method to be called. * @param args | Arguments of method. Arguments should be certain if method is overloaded! * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. * * @throws InvocationTargetException if called method throws and exception while calling! * @@ -146,7 +146,7 @@ public static Object InvokeFunc(Object obj, String name, Object... args) throws * @param name | Name of public static method to be called. * @param args | Arguments of method. Arguments should be certain if method is overloaded! * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. * * @throws InvocationTargetException if called method throws and exception while calling! * @@ -170,7 +170,7 @@ public static Object InvokeFunc(Object obj, Class objCls, String name, Object * @param argClasses | Classes of args. * @param args | Arguments of method. Arguments should be certain if method is overloaded! * - * @return The returned result of called method or {@link Serializer#VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. * * @throws InvocationTargetException if called method throws and exception while calling! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 1734435..9d82ce3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -36,7 +36,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * @param source | Source object to get value of the member from (may or may not be null). Source should not be modified! * @param member | Name/key of the member to get. * - * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
+ * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link #VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
* Note: This method is meant to be overridden in order to add support for accessing multiple sources because by default it supports only {@link GenericScope} * * @since 1.3.8 diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index c3f2d74..5e022f3 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -296,7 +296,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence)} + {@link Serializer#LoadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -304,7 +304,7 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File)} + {@link Serializer#LoadFrom(File, Object...)} {@link Reader} @@ -312,7 +312,7 @@ Obtained serializer content (return) {@link InputStream} - {@link Serializer#LoadFrom(InputStream)} + {@link Serializer#LoadFrom(InputStream, Object...)} {@link URL} @@ -346,7 +346,7 @@ public static JsonSerializer from(Object fromObj) throws Exception /** * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! * * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

* Table of specific Object --> JsonSerializer conversions: @@ -363,7 +363,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence)} + {@link Serializer#LoadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -371,7 +371,7 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File)} + {@link Serializer#LoadFrom(File, Object...)} {@link Reader} @@ -379,7 +379,7 @@ Obtained serializer content (return) {@link InputStream} - {@link Serializer#LoadFrom(InputStream)} + {@link Serializer#LoadFrom(InputStream, Object...)} {@link URL} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index cb77270..d86c0bb 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -784,7 +784,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence)} + {@link Serializer#LoadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -792,7 +792,7 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File)} + {@link Serializer#LoadFrom(File, Object...)} {@link Reader} @@ -800,7 +800,7 @@ Obtained serializer content (return) {@link InputStream} - {@link Serializer#LoadFrom(InputStream)} + {@link Serializer#LoadFrom(InputStream, Object...)} {@link URL} @@ -834,7 +834,7 @@ public static JussSerializer from(Object fromObj) throws Exception /** * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link GenericScope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! * * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

* Table of specific Object --> JussSerializer conversions: @@ -851,7 +851,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence)} + {@link Serializer#LoadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -859,7 +859,7 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File)} + {@link Serializer#LoadFrom(File, Object...)} {@link Reader} @@ -867,7 +867,7 @@ Obtained serializer content (return) {@link InputStream} - {@link Serializer#LoadFrom(InputStream)} + {@link Serializer#LoadFrom(InputStream, Object...)} {@link URL} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index dbeaf18..065248a 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -159,7 +159,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDe * @param genericVar | If true, member is expected be generic (not only string) and further parsing is required, may or may not be used... * @param args | Some additional args to be used in case of parsing that are provided by called, may or may not be used... * - * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link VOID} should be returned! + * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link #VOID} should be returned! * * @since 1.3.8 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index 5028812..9f72076 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -1,6 +1,5 @@ package org.ugp.serialx.juss.protocols; -import static org.ugp.serialx.Utils.Instantiate; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -12,7 +11,7 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; +import org.ugp.serialx.Utils; import org.ugp.serialx.protocols.SerializationProtocol; /** @@ -126,7 +125,7 @@ public AutoProtocol(Class applicableFor, boolean useScope, List applicableFor, boolean useScope, List objectClass) throws Exception { - return Instantiate(objectClass); + return Utils.Instantiate(objectClass); } @Override @@ -168,7 +167,7 @@ public T unserialize(Class objectClass, Object... args) throws Exce return Scope.into(obj, (Scope) args[0], fieldDescriptors); } - for (int i = 0, size = fieldDescriptors.size(); i < size && i < args.length; i++) + for (int i = 0, size = Math.min(fieldDescriptors.size(), args.length); i < size; i++) { Method setter = fieldDescriptors.get(i).getWriteMethod(); Type expectedType = setter.getGenericParameterTypes()[0]; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 39a34d7..796bd08 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -72,7 +72,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * @param obj2 | Object 2! * @param compareInstances | If true, this method will compare objects using == operator! * - * @return True supposed to be returned if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * @return True supposed to be returned if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! * * @since 1.3.2 */ @@ -147,7 +147,7 @@ public static boolean numberComparator(double d1, double d2, boolean isGreater, * @param obj1 | Object 1! * @param obj2 | Object 2! * - * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! * * @since 1.3.0 */ @@ -161,7 +161,7 @@ public static boolean equals(Object obj1, Object obj2) * @param obj2 | Object 2! * @param compareInstances | If true, this method will compare objects using == operator! * - * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! * * @since 1.3.2 */ diff --git a/pom.xml b/pom.xml index 85b0b8a..2d3b4dd 100644 --- a/pom.xml +++ b/pom.xml @@ -83,7 +83,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.8.0 -Xdoclint:none From 02ecf7106642602a4c16f90647126886012f2775 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Thu, 22 Aug 2024 21:47:55 +0200 Subject: [PATCH 41/75] docs fix --- .../src/main/java/org/ugp/serialx/Scope.java | 2 +- .../main/java/org/ugp/serialx/Serializer.java | 25 ++++++++++++++----- .../org/ugp/serialx/juss/JussSerializer.java | 4 +-- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index af25e9a..ff1108c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -116,7 +116,7 @@ public Scope clone() } /** - * @param objClass | Class of object to create using protocols. + * @param objClass | Class of object to create using protocols (may or may not support other implementations of {@link Type}). * @param protocolsToUse | Registry of protocols to use. * * @return Object of objClass constructed from this scopes independent values using protocol for objClass or null if there was no protocol found in protocolsToUse! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 72d167a..80d0c19 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -19,6 +19,7 @@ import java.io.OutputStreamWriter; import java.io.Reader; import java.io.StringReader; +import java.io.Writer; import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URL; @@ -160,7 +161,7 @@ public T toObjectOf(String variableWithscope, Class objClass, T defaultVa } /** - * @param type | Class of object to create. + * @param objClass | Class of object to create (may or may not support other implementations of {@link Type}). * * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in this {@link Serializer#getProtocols()}! * @@ -283,11 +284,25 @@ public void SerializeTo(File f) throws IOException public void SerializeTo(boolean append, File f, Object... args) throws IOException { //double t0 = System.nanoTime(); - BufferedWriter writer = new BufferedWriter(new FileWriter(f, append)); + Writer writer = new BufferedWriter(new FileWriter(f, append)); writer.write(Stringify(args)); writer.close(); + +// String serialized = Stringify(args); +// +// RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); +// FileChannel channel = fileOutputStream.getChannel(); +// +//// channel.write(ByteBuffer.wrap(serialized.getBytes())); +// +// ByteBuffer buff = channel.map(FileChannel.MapMode.READ_WRITE, append ? channel.size() : 0, serialized.length()); +// buff.put(serialized.getBytes()); +// +// channel.force(true); +// channel.close(); +// fileOutputStream.close(); } /** @@ -305,7 +320,7 @@ public String Stringify(Object... args) throws IOException } /** - * @param source | Source {@link OutputStream} to serialize variables and objects into! + * @param outputStream | Source {@link OutputStream} to serialize variables and objects into! * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! * * @return Source {@link OutputStream} with variables and objects serialized in specific format (may or may not be flushed). @@ -382,10 +397,8 @@ public S LoadFrom(InputStream stream, Object... parserArgs) /** * @param reader | Any {@link Reader} with serialized objects in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! * - * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. - * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! + * @return This scope after loading data from reader (you most likely want to return "this")! * * @since 1.2.5 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index d86c0bb..eb0a905 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -500,11 +500,11 @@ else if (ch == '}' || ch == ']') } /** - * @return Formated content of reader ready to parse! + * @return Formated content of reader ready to parse! Should not modify this object in any way! * * @since 1.3.2 */ - protected StringBuilder readAndFormat(Reader reader, boolean format) + public StringBuilder readAndFormat(Reader reader, boolean format) { int quote = 0, multLineCom = -1; //int brackets = 0, lastIndex = 0, delChars = 0; From 8e430645e06c94f8555092c19ecac8917a285854 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 25 Aug 2024 22:08:37 +0200 Subject: [PATCH 42/75] ... --- .../src/main/java/org/ugp/serialx/juss/JussSerializer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index eb0a905..fba97b1 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -408,7 +408,7 @@ public S LoadFrom(Reader reader, Object... args) if (args[3] == null) args[3] = getProtocols(); - StringBuilder str = readAndFormat(reader, formatRequired); + StringBuilder str = readAndFormat(reader, formatRequired); // TODO could be improved... List objs = splitAndParse(str, args); addAll(objs); From 50a08b3f67dae98b7d0ca6868679bc66ea07e6e2 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 8 Sep 2024 23:05:14 +0200 Subject: [PATCH 43/75] prepairing for release and fixing tiny bug --- README.md | 2 +- SerialX-core/pom.xml | 2 +- SerialX-devtools/pom.xml | 4 ++-- SerialX-json/pom.xml | 4 ++-- .../serialx/json/converters/JsonObjectConverter.java | 11 ++++++++--- SerialX-juss/pom.xml | 6 +++--- SerialX-operators/pom.xml | 4 ++-- pom.xml | 2 +- 8 files changed, 20 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 8f0b6c0..918a497 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # Java-SerialX dev -This branch is used for testing and stuff! +This the main development branch! diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index 1d7592f..4be9914 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -7,7 +7,7 @@ org.ugp.serialx - core + serialx-core 1.3.8 SerialX core diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 62408a9..8ea0304 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -7,7 +7,7 @@ org.ugp.serialx - devtools + serialx-devtools 1.3.8 SerialX devtools @@ -16,7 +16,7 @@ org.ugp.serialx - core + serialx-core ${revision} diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 099d015..c400bb5 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -7,7 +7,7 @@ org.ugp.serialx - json + serialx-json 1.3.8 SerialX json @@ -16,7 +16,7 @@ org.ugp.serialx - juss + serialx-juss ${revision} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index 09091ec..585b4e6 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -14,7 +14,7 @@ * * @author PETO * - * @since 1.3.5 + * @since 1.3.5 (separated from JsonSerializer since 1.3.8) */ public class JsonObjectConverter extends ObjectConverter { @@ -22,16 +22,21 @@ public class JsonObjectConverter extends ObjectConverter @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) { + if (arg == null) + return CONTINUE; + if (arg.getClass().isArray()) return super.toString(myHomeRegistry, new Scope(Utils.fromAmbiguousArray(arg)), args); if (arg instanceof Map) { Map map = (Map) arg; - if (map.isEmpty() || map.keySet().iterator().next() instanceof CharSequence) + if (map.isEmpty()) + return "{}"; + if (map.keySet().iterator().next() instanceof CharSequence) return super.toString(myHomeRegistry, new Scope((Map) map), args); } - + SerializationProtocol prot = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args); if (prot != null && !(arg instanceof Scope)) try diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index a37638a..2a1d974 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -7,16 +7,16 @@ org.ugp.serialx - juss + serialx-juss 1.3.8 - SerialX-juss + SerialX juss SerialX support for Java Universal Serial Script data format, custom default format of SerialX! org.ugp.serialx - core + serialx-core ${revision} diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index cf840c6..073c8a0 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -7,7 +7,7 @@ org.ugp.serialx - operators + serialx-operators 1.3.8 SerialX operators @@ -16,7 +16,7 @@ org.ugp.serialx - core + serialx-core ${revision} diff --git a/pom.xml b/pom.xml index 2d3b4dd..b0fb715 100644 --- a/pom.xml +++ b/pom.xml @@ -15,7 +15,7 @@ SerialX root - Store Java objects into file via SerialX. SerialX is a powerful utility library to serialize objects in Java programmatically via recursive descent parser for custom domain-specific languages! + Store Java objects into JSON or any format you want! SerialX is a powerful lightweight utility library to serialize Java objects programmatically via tweakable recursive descent parser for custom domain-specific languages! https://github.com/SimplyProgrammer/Java-SerialX 2020 From e8104b7f334556132ca2898a80b0d2685e89731b Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 8 Sep 2024 23:10:29 +0200 Subject: [PATCH 44/75] ... --- LICENSE | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 LICENSE diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7212173..0000000 --- a/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Based on MIT License - -Copyright (c) USP 2019-2020 | Peto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated files, to deal -in the Software without restriction, including without limitation the rights -to use, copy or modify copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -Permission to publish, distribute, sublicense or sell for example as content of some game or application is allowed -subject to the following conditions: Indication of the original source (https://github.com/PetoPetko/Java-SerialX/). - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software! - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. From 6023552e45dda8e230d9ae76bf9b08ab7042271e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 14 Sep 2024 00:25:02 +0200 Subject: [PATCH 45/75] Protocol "mode" is now bitwise based on bit-packing --- .../main/java/org/ugp/serialx/Registry.java | 8 +- .../serialx/converters/ProtocolConverter.java | 34 ++++++-- .../protocols/SerializationProtocol.java | 82 +++++++++---------- .../juss/converters/ObjectConverter.java | 4 +- .../protocols/SelfSerializableProtocol.java | 4 +- .../UniversalObjectInstantiationProtocol.java | 2 +- 6 files changed, 75 insertions(+), 59 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java index 0681b36..2531833 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java @@ -334,10 +334,10 @@ public C get(Class cls, boolean includeChildrens) for (int i = 0, size = size(); i < size; i++) { C elm = (C) get(i); - Class objCls = elm.getClass(); - if (objCls == cls) + Class objCls; + if ((objCls = elm.getClass()) == cls) return elm; - else if (includeChildrens && cls.isAssignableFrom(objCls)) + if (includeChildrens && cls.isAssignableFrom(objCls)) obj = elm; } return obj; @@ -371,7 +371,7 @@ public int indexOf(Class cls, boolean includeChildrens) Class objCls = get(i).getClass(); if (objCls == cls) return i; - else if (includeChildrens && cls.isAssignableFrom(objCls)) + if (includeChildrens && cls.isAssignableFrom(objCls)) index = i; } return index; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 2c7e923..b302814 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -73,6 +73,8 @@ public class ProtocolConverter implements DataConverter protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, Scope.class, Double.class, Float.class, String.class)); + protected long protocolType = 0; + @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) { @@ -153,7 +155,7 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objClass)) return objArgs[0]; compilerArgs[4] = oldObjectClass; - return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, objClass, objArgs); + return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, getProtocolType(), objClass, objArgs); } catch (Exception e) { @@ -189,7 +191,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ if (useBase64IfCan && obj instanceof Serializable) return CONTINUE; - if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE, args)) != null) + if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE | getProtocolType(), args)) != null) { Class oldObjectClass = null; try @@ -240,11 +242,9 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ @Override public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) { - if (obj instanceof Scope && ((Scope) obj).isEmpty()) - return "Empty scope!"; - else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) + if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) return "Multiline char sequence!"; - return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE_DESERIALIZE | getProtocolType(), argsUsedConvert)).append("!"); } /** @@ -276,6 +276,26 @@ public void setUseBase64IfCan(boolean useBase64IfCan) { this.useBase64IfCan = useBase64IfCan; } + + /** + * @return The additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). + * + * @since 1.3.8 + */ + public long getProtocolType() + { + return protocolType; + } + + /** + * @param protocolType | Value of additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). + * + * @since 1.3.8 + */ + public void setProtocolType(long protocolType) + { + this.protocolType = protocolType; + } /** * @return Classes that are eligible for public static member invocation (:: operator)!
@@ -298,7 +318,7 @@ public Set> getInvokableClasses() * * @since 1.3.5 */ - public static SerializationProtocol getProtocolFor(Object obj, byte mode, Object[] args) + public static SerializationProtocol getProtocolFor(Object obj, long mode, Object[] args) { if (args.length > 3) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 20e98a3..7316d46 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -26,7 +26,7 @@ public abstract class SerializationProtocol /** * This is serialization protocol registry. This is place where your {@link SerializationProtocol} implementations should be registered in order to work properly! Do not add there two protocols applicable for exactly same classes! * Also I recommend to register protocols in generic order of object that are they applicable for! In other words If some object Foo has child classes, protocol of these classes should be registered after each other. - * Defaultly there are registered protocols from ugp.org.SerialX.protocols. + * Defaultly there are registered protocols from org.ugp.serialx.protocols. * * @since 1.3.0 */ @@ -37,30 +37,30 @@ public abstract class SerializationProtocol * * @since 1.3.5 */ - public static final byte MODE_SERIALIZE = 0; + public static final long MODE_SERIALIZE = 0b01; /** * This mode is for protocols that are used for deserialization only! * * @since 1.3.5 */ - public static final byte MODE_DESERIALIZE = 1; + public static final long MODE_DESERIALIZE = 0b10; /** - * This mode is for protocols that chat can both serialize and deserialize! + * This mode is for protocols that chat can both serialize and deserialize (MODE_SERIALIZE | MODE_DESERIALIZE)! * - * @since 1.3.5 + * @since 1.3.8 (originally known as MODE_ALL) */ - public static final byte MODE_ALL = 2; + public static final long MODE_SERIALIZE_DESERIALIZE = MODE_SERIALIZE | MODE_DESERIALIZE; protected boolean isActive = true; @Override - public boolean equals(Object obj) + public boolean equals(Object obj) { if (obj instanceof Class) return applicableFor().equals(obj); - else if (obj instanceof SerializationProtocol) + if (obj instanceof SerializationProtocol) return applicableFor().equals(((SerializationProtocol) obj).applicableFor()); return super.equals(obj); } @@ -128,17 +128,16 @@ public T unserialize(Class objectClass, Scope scope) throws Excepti public abstract Class applicableFor(); /** - * @return Mode of this protocol. Default is {@link SerializationProtocol#MODE_ALL}! + * @return Mode of this protocol, describing its type or operation mode. Can be one or more chained with binary or. Default is {@link SerializationProtocol#MODE_SERIALIZE_DESERIALIZE}! * - * @see SerializationProtocol#MODE_ALL * @see SerializationProtocol#MODE_DESERIALIZE * @see SerializationProtocol#MODE_SERIALIZE * * @since 1.3.5 */ - public byte getMode() + public long getMode() { - return MODE_ALL; + return MODE_SERIALIZE_DESERIALIZE; } /** @@ -174,11 +173,12 @@ public void setActive(boolean isActive) */ public static Object[] serializeObj(O object) throws Exception { - return serializeObj(REGISTRY, object); + return serializeObj(REGISTRY, 0, object); } /** * @param registry | Registry to use! + * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. * @param object | The object. * * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from registry. @@ -186,9 +186,9 @@ public static Object[] serializeObj(O object) throws Exception * * @since 1.3.0 */ - public static Object[] serializeObj(ProtocolRegistry registry, O object) throws Exception + public static Object[] serializeObj(ProtocolRegistry registry, long aditionalType, O object) throws Exception { - SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE); + SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE | aditionalType); if (prot == null) { LogProvider.instance.logErr("Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); @@ -210,11 +210,12 @@ public static Object[] serializeObj(ProtocolRegistry registry, O object) thr */ public static O unserializeObj(Class objectClass, Object... args) throws Exception { - return unserializeObj(REGISTRY, objectClass, args); + return unserializeObj(REGISTRY, 0, objectClass, args); } /** * @param registry | Registry to use! + * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! * @param args | Args to create obj {@link T} from. * @@ -226,9 +227,9 @@ public static O unserializeObj(Class objectClass, Object... arg * @since 1.3.0 */ @SuppressWarnings("unchecked") - public static O unserializeObj(ProtocolRegistry registry, Class objectClass, Object... args) throws Exception + public static O unserializeObj(ProtocolRegistry registry, long aditionalType, Class objectClass, Object... args) throws Exception { - SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE); + SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE | aditionalType); if (prot == null) { LogProvider.instance.logErr("Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); @@ -302,68 +303,65 @@ public void add(int index, SerializationProtocol element) /** * @param protocolsClass | Protocols class. * - * @return Protocol by its class. + * @return Protocol by its class. Pretty much equivalent with {@link Registry#get(Class)}. * * @since 1.0.0 */ public SerializationProtocol getProtocolByClass(Class> protocolsClass) { - for (SerializationProtocol p : this) - if (p.getClass().equals(protocolsClass)) - return p; - return null; + return get(protocolsClass); } /** - * @return Sublist of protocols that are active and can be used. + * @return Sublist of any protocols that are active and can be used. * * @since 1.0.0 */ public List> GetActiveProtocols() { - return GetActiveProtocols(MODE_ALL); + return GetActiveProtocols(-1); } /** - * @return Sublist of protocols that are not active and can't be used. + * @return Sublist of any protocols that are not active and can't be used. * * @since 1.0.0 */ public List> GetDeactivatedProtocols() { - return GetDeactivatedProtocols(MODE_ALL); + return GetDeactivatedProtocols(-1); } /** - * @param mode | Mode of protocol to find. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. * * @return Sublist of protocols that are active and can be used according to mode. * * @since 1.3.5 */ - public List> GetActiveProtocols(byte mode) + public List> GetActiveProtocols(long mode) { List> resault = new ArrayList<>(); for (SerializationProtocol p : this) - if (p.isActive() && (p.getMode() == 2 || p.getMode() == mode)) + if (p.isActive() && (p.getMode() & mode) != 0) resault.add(p); return resault; } /** - * @param mode | Mode of protocol to find. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. * * @return Sublist of protocols that are not active and can't be used according to mode. * * @since 1.3.5 */ - public List> GetDeactivatedProtocols(byte mode) + public List> GetDeactivatedProtocols(long mode) { List> resault = new ArrayList<>(); for (SerializationProtocol p : this) - if (!p.isActive() && (p.getMode() == 2 || p.getMode() == mode)) + if (!p.isActive() && (p.getMode() & mode) != 0) resault.add(p); return resault; } @@ -378,7 +376,7 @@ public List> GetDeactivatedProtocols(byte mode) */ public SerializationProtocol GetProtocolFor(O obj) { - return GetProtocolFor(obj, MODE_ALL); + return GetProtocolFor(obj, MODE_SERIALIZE_DESERIALIZE); } /** @@ -391,20 +389,20 @@ public SerializationProtocol GetProtocolFor(O obj) */ public SerializationProtocol GetProtocolFor(Class applicableFor) { - return GetProtocolFor(applicableFor, MODE_ALL); + return GetProtocolFor(applicableFor, MODE_SERIALIZE_DESERIALIZE); } /** * @param * @param obj | Object that is required protocol applicable for. - * @param mode | Mode of protocol to find. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. * * @return Protocol applicable for required objects class according to mode or null if there is no such an active protocol! * * @since 1.3.5 */ @SuppressWarnings("unchecked") - public SerializationProtocol GetProtocolFor(O obj, byte mode) + public SerializationProtocol GetProtocolFor(O obj, long mode) { return (SerializationProtocol) GetProtocolFor(obj.getClass(), mode); } @@ -412,25 +410,25 @@ public SerializationProtocol GetProtocolFor(O obj, byte mode) /** * @param * @param applicableFor | Class of object that is protocol applicable for. - * @param mode | Mode of protocol to find. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. * * @return Protocol applicable for required class according to mode or null if there is no such an active protocol! * * @since 1.3.5 */ @SuppressWarnings("unchecked") - public SerializationProtocol GetProtocolFor(Class applicableFor, byte mode) + public SerializationProtocol GetProtocolFor(Class applicableFor, long mode) { SerializationProtocol protocol = null; - for (int i = 0, len = size(), myMode = 0; i < len; i++) + for (int i = 0, len = size(); i < len; i++) { SerializationProtocol p = get(i); - if (p.isActive() && ((myMode = p.getMode()) == 2 || myMode == mode)) + if (p.isActive() && (p.getMode() & mode) != 0) { Class applicable = p.applicableFor(); if (applicable == applicableFor) return (SerializationProtocol) p; - else if (applicable.isAssignableFrom(applicableFor)) + if (applicable.isAssignableFrom(applicableFor)) protocol = (SerializationProtocol) p; } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 52e14c9..43d35f7 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -190,9 +190,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob { if (obj instanceof Scope && ((Scope) obj).isEmpty()) return "Empty scope!"; - else if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) - return "Multiline char sequence!"; - return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_ALL, argsUsedConvert).toString()).append("!"); + return super.getDescription(myHomeRegistry, obj, argsUsedConvert); } /** diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index 3afe55f..9247b8a 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -29,9 +29,9 @@ public Object[] serialize(T object) } @Override - public byte getMode() + public long getMode() { - return MODE_ALL; + return MODE_SERIALIZE_DESERIALIZE; } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index cf60821..d8df934 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -92,7 +92,7 @@ public Class applicableFor() } @Override - public byte getMode() + public long getMode() { return MODE_DESERIALIZE; } From 26fe8ec098e48648bdc3d64937e914047af29071 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 21 Sep 2024 00:44:53 +0200 Subject: [PATCH 46/75] final formating an committing --- SerialX-core/pom.xml | 30 +-- .../java/org/ugp/serialx/GenericScope.java | 6 +- .../serialx/converters/StringConverter.java | 8 +- .../serialx/converters/imports/Import.java | 4 +- SerialX-devtools/pom.xml | 46 ++-- SerialX-json/pom.xml | 46 ++-- SerialX-juss/pom.xml | 46 ++-- SerialX-operators/pom.xml | 46 ++-- .../operators/ComparisonOperators.java | 8 +- pom.xml | 221 +++++++++--------- 10 files changed, 240 insertions(+), 221 deletions(-) diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index 4be9914..db84da8 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -1,15 +1,17 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-core - 1.3.8 - - SerialX core - Core of SerialX. Contains core features and utilities shared across the library. + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-core + 1.3.8 + + SerialX core + Core of SerialX. Contains core features and utilities shared across the library. \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 5e9cdb9..1e4ef01 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -104,11 +104,11 @@ public boolean equals(Object obj) { if (obj instanceof GenericScope) return values().equals(((GenericScope) obj).values()) && variables().equals(((GenericScope) obj).variables()); - else if (obj instanceof Collection) + if (obj instanceof Collection) return variablesCount() <= 0 && values().equals(obj); - else if (obj instanceof Map) + if (obj instanceof Map) return valuesCount() <= 0 && variables().equals(obj); - else if (obj != null && obj.getClass().isArray()) + if (obj != null && obj.getClass().isArray()) return variablesCount() <= 0 && Objects.deepEquals(toArray(), Utils.fromAmbiguousArray(obj)); return super.equals(obj); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 2e61b8b..98dd99a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -79,12 +79,12 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object.. str = "{"+str+"}"; return str; } - else if (serializeStringNormally) + + if (serializeStringNormally) { if (contains(str, '\"', '\n', '\r')) return CONTINUE; - else - return "\""+str+"\""; + return "\""+str+"\""; } } return CONTINUE; @@ -158,4 +158,4 @@ public static String DirectCode(Object obj) { return "${" + obj + "}"; } -} +} \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java index e2a9662..b3a3e97 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -92,9 +92,9 @@ public boolean equals(Object obj) { if (obj instanceof String) return getClsAlias().equals(obj); - else if (obj instanceof Class) + if (obj instanceof Class) return getCls().equals(obj); - else if (obj instanceof Import) + if (obj instanceof Import) return getClsAlias().equals(((Import) obj).getClsAlias()) && getCls().equals(((Import) obj).getCls()); return super.equals(obj); } diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 8ea0304..3b77dd3 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -1,23 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-devtools - 1.3.8 - - SerialX devtools - Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. - - - - org.ugp.serialx - serialx-core - ${revision} - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-devtools + 1.3.8 + + SerialX devtools + Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. + + + + org.ugp.serialx + serialx-core + ${revision} + + \ No newline at end of file diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index c400bb5..047c32d 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -1,23 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-json - 1.3.8 - - SerialX json - SerialX Json support - - - - org.ugp.serialx - serialx-juss - ${revision} - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-json + 1.3.8 + + SerialX json + SerialX Json support + + + + org.ugp.serialx + serialx-juss + ${revision} + + \ No newline at end of file diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index 2a1d974..9714d8d 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -1,23 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-juss - 1.3.8 - - SerialX juss - SerialX support for Java Universal Serial Script data format, custom default format of SerialX! - - - - org.ugp.serialx - serialx-core - ${revision} - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-juss + 1.3.8 + + SerialX juss + SerialX support for Java Universal Serial Script data format, custom default format of SerialX! + + + + org.ugp.serialx + serialx-core + ${revision} + + \ No newline at end of file diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index 073c8a0..067d22a 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -1,23 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-operators - 1.3.8 - - SerialX operators - This modul contains basic operators contained in almost every programing language... - - - - org.ugp.serialx - serialx-core - ${revision} - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-operators + 1.3.8 + + SerialX operators + This modul contains basic operators contained in almost every programing language... + + + + org.ugp.serialx + serialx-core + ${revision} + + \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 796bd08..40d8e0b 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -117,13 +117,13 @@ public static Object toCompareFriendly(Object obj) { if (obj instanceof Map) return ((Map) obj).size(); - else if (obj instanceof Collection) + if (obj instanceof Collection) return ((Collection) obj).size(); - else if (obj instanceof Scope) + if (obj instanceof Scope) return ((Scope) obj).valuesCount() + ((Scope) obj).variablesCount(); - else if (obj instanceof CharSequence) + if (obj instanceof CharSequence) return ((CharSequence) obj).length(); - else if ((obj = ArithmeticOperators.toNum(obj)).getClass().isArray()) + if ((obj = ArithmeticOperators.toNum(obj)).getClass().isArray()) return Array.getLength(obj); return obj; } diff --git a/pom.xml b/pom.xml index b0fb715..28f89c6 100644 --- a/pom.xml +++ b/pom.xml @@ -1,115 +1,124 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - pom - - - SerialX-json - SerialX-core - SerialX-devtools - SerialX-operators - SerialX-juss - - - SerialX root - Store Java objects into JSON or any format you want! SerialX is a powerful lightweight utility library to serialize Java objects programmatically via tweakable recursive descent parser for custom domain-specific languages! - https://github.com/SimplyProgrammer/Java-SerialX - 2020 - - - - Custom license - https://github.com/SimplyProgrammer/Java-SerialX/blob/master/LICENSE - - - - - - SimplyProgrammer - petko.hupka@gmail.com - org.ugp - https://github.com/SimplyProgrammer/ - - - - - scm:git:git://github.com/SimplyProgrammer/Java-SerialX.git - scm:git:ssh://github.com:SimplyProgrammer/Java-SerialX.git - https://github.com/SimplyProgrammer/ - - - - 8 - 1.3.8 - + + 4.0.0 + + org.ugp + serialx + ${revision} + pom + + + SerialX-json + SerialX-core + SerialX-devtools + SerialX-operators + SerialX-juss + + + SerialX root + Store Java objects into JSON or any format you want! SerialX is a powerful lightweight utility library to serialize Java objects programmatically via tweakable recursive descent parser for custom domain-specific languages! + https://github.com/SimplyProgrammer/Java-SerialX + 2020 + + + + Custom license + https://github.com/SimplyProgrammer/Java-SerialX/blob/master/LICENSE + + + + + + SimplyProgrammer + petko.hupka@gmail.com + org.ugp + https://github.com/SimplyProgrammer/ + + + + + scm:git:git://github.com/SimplyProgrammer/Java-SerialX.git + scm:git:ssh://github.com:SimplyProgrammer/Java-SerialX.git + https://github.com/SimplyProgrammer/ + + + + + github + https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX + + + + + 8 + 1.3.8 + UTF-8 - ${java.version} - ${java.version} - - serialx-${project.artifactId}-${project.version} + ${java.version} + ${java.version} + + serialx-${project.artifactId}-${project.version} ${project.build.finalName} - + - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - - ${java.version} - ${java.version} - - eclipse - - - - org.codehaus.plexus - plexus-compiler-eclipse - 2.9.0 - - - org.eclipse.jdt - ecj - 3.25.0 - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.8.0 - - - -Xdoclint:none - -Xdoclint:none - - - - - - jar - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - - jar - - - - + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + ${java.version} + ${java.version} + + eclipse + + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.9.0 + + + org.eclipse.jdt + ecj + 3.25.0 + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.8.0 + + + -Xdoclint:none + -Xdoclint:none + + + + + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + + jar + + + + \ No newline at end of file From e32102f25c13556ce8168fe3079b697c23f35bfa Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 22 Sep 2024 22:05:43 +0200 Subject: [PATCH 47/75] mvn flatten --- .gitignore | 1 + pom.xml | 27 ++++++++++++++++++++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 2957f58..e2e18c1 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ Thumbs.db UserInterfaceState.xcuserstate $RECYCLE.BIN/ +.flattened-* *.log log.txt npm-debug.log* diff --git a/pom.xml b/pom.xml index 28f89c6..7abb0bd 100644 --- a/pom.xml +++ b/pom.xml @@ -17,7 +17,12 @@ SerialX root - Store Java objects into JSON or any format you want! SerialX is a powerful lightweight utility library to serialize Java objects programmatically via tweakable recursive descent parser for custom domain-specific languages! + + Store Java objects into JSON or any format you want! SerialX is + a powerful lightweight utility library to serialize Java objects + programmatically via tweakable recursive descent parser for custom + domain-specific languages! + https://github.com/SimplyProgrammer/Java-SerialX 2020 @@ -58,11 +63,11 @@ ${java.version} ${java.version} - serialx-${project.artifactId}-${project.version} + - ${project.build.finalName} + @@ -89,6 +94,7 @@ + org.apache.maven.plugins maven-javadoc-plugin @@ -119,6 +125,21 @@ + + org.codehaus.mojo + flatten-maven-plugin + 1.6.0 + + + + flatten + process-resources + + flatten + + + + \ No newline at end of file From db4d7a0fb027e117b7a71cca89ffe673bfd894fa Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 22 Sep 2024 22:17:49 +0200 Subject: [PATCH 48/75] Java 21+ supported --- SerialX-core/src/main/java/org/ugp/serialx/Serializer.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 80d0c19..f8dfda4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -22,6 +22,7 @@ import java.io.Writer; import java.lang.reflect.Type; import java.net.HttpURLConnection; +import java.net.URI; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; @@ -740,7 +741,7 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN { if (indexOfNotInObj((CharSequence) obj, "http") == 0) { - URLConnection con = new URL(obj.toString()).openConnection(); + URLConnection con = new URI(obj.toString()).toURL().openConnection(); con.setDoOutput(true); if (con instanceof HttpURLConnection) post(fromSerializer, (HttpURLConnection) con); @@ -831,7 +832,7 @@ public static Serializer from(Serializer newInstance, Object fromObj, String... { String fromStr; if (indexOfNotInObj(fromStr = fromObj.toString(), "http") == 0) - return newInstance.LoadFrom(new URL(fromStr).openStream()); + return newInstance.LoadFrom(new URI(fromStr).toURL().openStream()); return newInstance.LoadFrom(new File(fromStr)); } catch (Exception e) From a6d5112635213cc193d017fbb03536ddddcd78f9 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 17 Jun 2025 14:46:39 +0200 Subject: [PATCH 49/75] prep for optimizations --- .../main/java/org/ugp/serialx/Serializer.java | 20 +- SerialX-juss/pom.xml | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 193 +++++++++++------- .../juss/converters/ObjectConverter.java | 20 +- SerialX-operators/pom.xml | 2 +- .../operators/ArithmeticOperators.java | 22 +- 6 files changed, 174 insertions(+), 85 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index f8dfda4..4d961da 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -353,13 +353,13 @@ public OutputStream SerializeTo(OutputStream outputStream, Object... args) throw * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! * - * @throws FileNotFoundException if file does not exist! + * @throws FileNotFoundException if file does not exist or cannot be read! * * @since 1.0.0 * * @see Serializer#LoadFrom(Reader, Object...) */ - public S LoadFrom(File file, Object... parserArgs) throws FileNotFoundException + public S LoadFrom(File file, Object... parserArgs) throws IOException { return LoadFrom(new FileReader(file), parserArgs); } @@ -371,11 +371,13 @@ public S LoadFrom(File file, Object... parserArgs) throws File * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! * + * @throws IOException When reading the char sequence fails... + * * @since 1.2.5 * * @see Serializer#LoadFrom(Reader, Object...) */ - public S LoadFrom(CharSequence str, Object... parserArgs) + public S LoadFrom(CharSequence str, Object... parserArgs) throws IOException { return LoadFrom(new StringReader(str.toString()), parserArgs); } @@ -387,11 +389,13 @@ public S LoadFrom(CharSequence str, Object... parserArgs) * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! * + * @throws IOException When reading the input stream fails... + * * @since 1.3.2 * * @see Serializer#LoadFrom(Reader, Object...) */ - public S LoadFrom(InputStream stream, Object... parserArgs) + public S LoadFrom(InputStream stream, Object... parserArgs) throws IOException { return LoadFrom(new InputStreamReader(stream), parserArgs); } @@ -401,9 +405,11 @@ public S LoadFrom(InputStream stream, Object... parserArgs) * * @return This scope after loading data from reader (you most likely want to return "this")! * + * @throws IOException When reading the reader fails... + * * @since 1.2.5 */ - public S LoadFrom(Reader reader) + public S LoadFrom(Reader reader) throws IOException { return LoadFrom(reader, true); } @@ -414,9 +420,11 @@ public S LoadFrom(Reader reader) * * @return This scope after loading data from reader (you most likely want to return "this")! * + * @throws IOException When reading the reader fails... + * * @since 1.3.2 */ - public abstract S LoadFrom(Reader reader, Object... parserArgs); + public abstract S LoadFrom(Reader reader, Object... parserArgs) throws IOException; /** * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index 9714d8d..e1786c6 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-juss - 1.3.8 + 1.3.9-SNAPSHOT SerialX juss SerialX support for Java Universal Serial Script data format, custom default format of SerialX! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index fba97b1..93d2dd9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -392,11 +392,13 @@ public Appendable GenerateComment(Appendable source, ParserRegistry registry, Ob * * @return This scope after loading data from reader (you most likely want to return "this")! * + * @throws IOException When reading the reader fails... + * * @since 1.3.2 */ @SuppressWarnings("unchecked") @Override - public S LoadFrom(Reader reader, Object... args) + public S LoadFrom(Reader reader, Object... args) throws IOException { boolean formatRequired = true; @@ -412,91 +414,140 @@ public S LoadFrom(Reader reader, Object... args) List objs = splitAndParse(str, args); addAll(objs); - //double t0 = System.nanoTime(); - /*Registry reg = DataParser.REGISTRY; - String lastLine = null; - int quote = 0, multLineCom = -1, brackets = 0; - try + if (parent == null) + getImports().removeImportsOf(this); + return (S) this; + } + + public void readAndParse(Reader reader) throws IOException + { + final char endl = System.lineSeparator().charAt(0); + +// StringBuilder str = readAndFormat(reader, formatRequired); // TODO could be improved... +// List objs = splitAndParse(str, args); +// addAll(objs); + + StringBuilder sb = new StringBuilder(); + char[] chars = new char[128*2]; + + for (int charsRead, oldCh = 0, state = 0, brackets; (charsRead = reader.read(chars)) != -1; ) { - BufferedReader lineReader = new BufferedReader(reader); - //String blanks = new String(new char[] {32, 9, 10, 12, 13}); - for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) + int i = 0; + switch (state) // Complete the unfinished action from prev iter based on state // <- Too much repetitive code already, and pain in the ass to work around with, consider other solution { - for (int i = 0, len = line.length(), com = -1, lastIndex = 0; i < len; i++) - { - char ch = line.charAt(i); - if (ch == '/' && i < len-1 && line.charAt(i+1) == '/') - com++; - else if (multLineCom <= -1 && ch == '"') - quote++; - - boolean notString = quote % 2 == 0; - if (multLineCom > -1 || com > -1) //Is comment + case '/': // Handle ongoing comments... + do if (chars[i] == endl) // Skip all until endl { - if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') - com = multLineCom = -1; + oldCh = state = 0; + i++; + break; } - else if (notString && ch == '/' && i < len-1 && line.charAt(i+1) == '*') - i += multLineCom = 1; - /*else if (notString && blanks.indexOf(ch) > -1) + while (++i < charsRead); + + break; + case '*': + do if (chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/') // Skip all until */ { - if ((chBefore = i > 0 ? line.charAt(i-1) : 0) != ';' && chBefore != '{' && blanks.indexOf(chBefore) <= -1) - sb.append(" "); - }*/ - /*else if (notString && i < str.length()-1 && (ch == '!' && str.charAt(i+1) == '!' || ch == '-' && str.charAt(i+1) == '-' || ch == '+' && str.charAt(i+1) == '+')) - i++;* - else + oldCh = state = 0; + i++; + break; + } + while (++i < charsRead); + + break; + + case '\"': + case '\'': + do // Append all chars until end of str/char { - if (notString) + char ch; + sb.append(ch = chars[i]); + if (ch == state) { - if (ch | ' ') == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') + state = 0; + i++; + break; + } + } + while (++i < charsRead); + + break; +// case ' ': +// do if (chars[i] > 32) // Skip all blanks until next non-blank +// { +// state = 0; +// //i++; +// break; +// } +// while (++i < charsRead); +// +// break; + } + + charsLoop: for (; i < charsRead; i++) + { + int ch = chars[i]; + if (ch < 33) // Handle blanks, skip unnecessary + { + if (oldCh > 32) // First blank (in possible row) + sb.append(oldCh /*= state*/ = ' '); + continue; + } + + if (oldCh == '/') // Skip the comments... + { + if (ch == '/') // // + { + for (state = '/'; ++i < charsRead; ); // Skip all until endl + if (chars[i] == endl) { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + line); + oldCh = state = 0; + continue charsLoop; } - else if (brackets == 0 && (ch == ';' || ch == ',')) + } + else if (ch == '*') // /* + { + for (state = '*'; ++i < charsRead; ) // Skip all until */ + if (chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/') // */ { - //System.out.println(lastIndex + " " + i); - String str = line.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i); - //System.out.println(str); - if (!(str = str.trim()).isEmpty()) - { - Object obj = ParseObjectHandleNull(reg, str, true, result); - if (obj != VOID) - result.add(obj); - } + oldCh = state = 0; + continue charsLoop; } + } + + continue; + } + + if (ch == '\"' || ch == '\'') + { + sb.append(ch); + for (state = ch; ++i < charsRead; ) // Append all chars until end of str/char + { + sb.append(ch = chars[i]); + if (ch == state) + { + state = 0; + break; } } } - lastLine = line; + else if ((ch | ' ') == '{') + { + for (brackets = 1; ++i < charsRead && brackets != 0; ) + { + if ((ch = (chars[i] | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < charsRead && chars[i] != '"'); + } + } + + oldCh = ch; } - lineReader.close(); - } - catch (IOException e) - { - e.printStackTrace(); } - //double t = System.nanoTime(); - //System.out.println((t-t0)/1000000); - if (lastLine != null && indexOfNotInObj(lastLine, ';', ',') <= -1) - { - if (!(lastLine = lastLine.trim()).isEmpty()) - { - Object obj = ParseObjectHandleNull(reg, lastLine, true, result); - if (obj != VOID) - result.add(obj); - } - }*/ - - if (parent == null) - getImports().removeImportsOf(this); - return (S) this; } /** @@ -589,7 +640,7 @@ else if (ch == '}' || ch == ']') * * @since 1.3.2 */ - protected List splitAndParse(StringBuilder formattedStr, Object... parserArgs) + public List splitAndParse(StringBuilder formattedStr, Object... parserArgs) { List result = new ArrayList<>(); @@ -624,6 +675,7 @@ else if (ch == '"') else if ((ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) { String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); + System.out.println(str + "\n"); if (!str.isEmpty()) { Object obj = parseObject(reg, str, parserArgs); @@ -635,6 +687,7 @@ else if (ch == '"') } String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); + System.out.println(str + "\n"); if (!str.isEmpty()) { Object obj = parseObject(reg, str, parserArgs); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 43d35f7..ebcf6cd 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -9,6 +9,7 @@ import java.util.Base64; import org.ugp.serialx.GenericScope; +import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataParser; @@ -113,9 +114,22 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile scope = getPreferredSerializer(); } - compilerArgs = compilerArgs.clone(); - compilerArgs[0] = false; //No extra formating... - return str.isEmpty() ? scope : scope.LoadFrom(new StringReader(str), compilerArgs); + if (compilerArgs.length > 0) + { + compilerArgs = compilerArgs.clone(); + compilerArgs[0] = false; //No extra formating... + } + + if (str.isEmpty()) + return scope; + try + { + return scope.LoadFrom(new StringReader(str), compilerArgs); + } + catch (IOException e) + { + LogProvider.instance.logErr("Unable to parse the scope because:", e); // Should not occur... + } } } return CONTINUE; diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index 067d22a..c28998b 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-operators - 1.3.8 + 1.3.9-SNAPSHOT SerialX operators This modul contains basic operators contained in almost every programing language... diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 55b3039..47dd813 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -59,18 +59,18 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) int index = 1; try { - for (int opPrio = 2; opPrio > 0; opPrio--) + for (int opPrio = getHighestPriority(); opPrio > 0; opPrio--) for (ListIterator iter = oprs.listIterator(); iter.hasNext(); ) { if (getOperatorPriority(op = iter.next()) == opPrio) { iter.remove(); - cofs.set(index = iter.nextIndex(), operator(cofs.get(index), op, cofs.remove(index + 1))); + cofs.set(index = iter.nextIndex(), operator(cofs.get(index), op, cofs.remove(index + 1), myHomeRegistry, args)); } } for (index = 1; (op = oprs.poll()) != null; ) - cofs.set(0, operator(cofs.get(0), op, cofs.get(index++))); + cofs.set(0, operator(cofs.get(0), op, cofs.get(index++), myHomeRegistry, args)); } catch (ClassCastException ex) { @@ -94,12 +94,14 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) * @param opr1 | Operand 1 * @param op | The operator/operation * @param opr2 | Operand 2 + * @param myHomeRegistry | Registry provided by the caller, use only in special cases! + * @param args | Some additional args provided by the caller for the myHomeRegistry, use only in special cases! * * @return Result of binary operation described by op between opr1 and opr2! If operator is not known, opr1 will be returned by default! * * @since 1.3.8 */ - public Object operator(Object opr1, String op, Object opr2) + public Object operator(Object opr1, String op, Object opr2, ParserRegistry myHomeRegistry, Object... args) { // System.err.println(opr1 + op + opr2); switch (op.charAt(0)) @@ -125,6 +127,8 @@ public Object operator(Object opr1, String op, Object opr2) * * @return Priority of provided operator (higher number = higher priority, 2 = high, 1 = medium, 0 = low) * + * @see ArithmeticOperators#getHighestPriority() + * * @since 1.3.8 */ public byte getOperatorPriority(String op) @@ -142,6 +146,16 @@ public byte getOperatorPriority(String op) } } + /** + * @return Number representing highest possible priority of operator (default is 2). + * + * @since 1.3.9 + */ + protected byte getHighestPriority() + { + return 2; + } + /** * @return Addition of cof and cof2 (cof + cof2) supposed to be returned! * From d16d2ecafe5520983d212c9ad43b572d0d25f538 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Tue, 8 Jul 2025 22:21:43 +0200 Subject: [PATCH 50/75] finishing and testing readAndParse, implementing ability for custom formating at Serializer lvl + ability to disable formatting completely (important), modif. some converters accordingly (Json specif logic separation into JsonVarConverter...). Optimizations and small API changes --- SerialX-core/pom.xml | 2 +- .../main/java/org/ugp/serialx/Serializer.java | 74 +++- .../src/main/java/org/ugp/serialx/Utils.java | 30 +- .../serialx/converters/BooleanConverter.java | 2 +- .../serialx/converters/ProtocolConverter.java | 53 ++- .../converters/imports/ImportsProvider.java | 2 +- SerialX-devtools/pom.xml | 2 +- SerialX-json/pom.xml | 4 +- .../org/ugp/serialx/json/JsonSerializer.java | 17 +- .../converters/JsonVariableConverter.java | 19 + SerialX-juss/pom.xml | 2 +- .../org/ugp/serialx/juss/JussSerializer.java | 362 +++++++++++------- .../juss/converters/ArrayConverter.java | 61 ++- .../juss/converters/ObjectConverter.java | 23 +- .../juss/converters/VariableConverter.java | 63 ++- SerialX-operators/pom.xml | 2 +- pom.xml | 2 +- 17 files changed, 464 insertions(+), 256 deletions(-) create mode 100644 SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index db84da8..ea51a11 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-core - 1.3.8 + 1.3.9-SNAPSHOT SerialX core Core of SerialX. Contains core features and utilities shared across the library. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 4d961da..1f55ed1 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -59,6 +59,8 @@ public abstract class Serializer extends Scope protected ParserRegistry parsers; protected ProtocolRegistry protocols; + protected byte format = 0; + /** * @param values | Initial independent values to be added in to this scope! * @@ -257,6 +259,7 @@ public String toString(boolean serialize) throws IOException /** * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! * * @return String with variables and objects serialized in specific format. * @@ -264,9 +267,9 @@ public String toString(boolean serialize) throws IOException * * @since 1.1.5 */ - public void SerializeTo(File f) throws IOException + public void SerializeTo(File f, Object... args) throws IOException { - SerializeTo(false, f); + SerializeTo(false, f, args); } /** @@ -472,9 +475,23 @@ public T emptyClone(T newEmptyInstance, GenericScope A SerializeAsSubscope(A source, Object... args) th * @since 1.3.5 */ @SuppressWarnings("unchecked") - public A SerializeAsSubscope(A source, char[] wrappingBrackets, Object... args) throws IOException + public A SerializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException { - int tabs = 0; - if (args.length > 1 && args[1] instanceof Integer) + source.append(wrappingBrackets[0]); + if (isEmpty()) + return (A) source.append(wrappingBrackets[1]); + + if (format == 0) // No format... { - tabs = (int) args[1]; - args[1] = tabs + 1; + if (args.length > 1 && args[1] instanceof Integer) + args[1] = ((int) args[1]) + 1; + return (A) SerializeTo(source, args).append(wrappingBrackets[1]); } - source.append(wrappingBrackets[0]); - if (!isEmpty()) - source = (A) SerializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)); - return (A) source.append(wrappingBrackets[1]); + + int tabs; + if (args.length > 1 && args[1] instanceof Integer) + args[1] = (tabs = (int) args[1]) + 1; + else + tabs = 0; + + return (A) SerializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)) + .append(wrappingBrackets[1]); } /** @@ -648,6 +674,28 @@ public T getParsed(String variableWithStringValue, Object... args) { return (T) getParsers().parse(getString(variableWithStringValue), args); } + + /** + * @return Non 0 value if proper indentation and newline characters should be used when serializing. Default is 0, no formating... + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#SerializeTo(Appendable, Object...)} + * + * @since 1.3.9 + */ + public byte getFormat() + { + return format; + } + + /** + * @param format | A non 0 value if proper indentation and newline characters should be used when serializing. + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#SerializeTo(Appendable, Object...)} + * + * @since 1.3.9 + */ + public void setFormat(byte format) + { + this.format = format; + } /** * @param obj | Object to map the serializer variables into! @@ -773,7 +821,7 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN return (T) Scope.into(obj, fromSerializer, fieldNamesToUse); } - + /** * @param newInstance | New instance of specific {@link Serializer} * @param fromObj | Object to create serializer from! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 37b2d5b..2d7d01e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -17,6 +17,7 @@ import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Map; @@ -35,6 +36,13 @@ public final class Utils { private Utils() {} + /** + * {@link System#lineSeparator()} + * + * @since 1.3.9 + */ + public static final char[] ENDL = System.lineSeparator().toCharArray(); + /** * @param f | Source file. * @@ -235,7 +243,7 @@ public static T Clone(T obj) * @since 1.3.2 */ @SuppressWarnings("unchecked") - public static T Clone(T obj, Registry parsersToUse, Object[] converterArgs, Object... parserArgs) + public static T Clone(T obj, Collection parsersToUse, Object[] converterArgs, Object... parserArgs) { if (obj == null) return null; @@ -749,18 +757,16 @@ public static String fastReplace(String str, String target, CharSequence replace * @param ch | Char to compare! * @param chars | Chars to match! * - * @return True if inserted char is any of inserted chars! + * @return True if inserted char (ch) is any of inserted chars! * * @since 1.3.0 */ public static boolean isOneOf(int ch, char... chars) { - if (chars.length > 0) - { - for (int i = 0, len = chars.length; i < len; i++) - if (chars[i] == ch) - return true; - } + final int charsLen = chars.length; + for (int i = 0; i < charsLen; i++) + if (chars[i] == ch) + return true; return false; } @@ -821,7 +827,7 @@ public static String showPosInString(CharSequence str, int pos) try { - if (contains(str, '\n', '\r')) + if (contains(str, ENDL)) return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); } @@ -881,14 +887,14 @@ public static Object[] fromAmbiguousArray(Object array) { if (array instanceof Object[]) return (Object[]) array; - - int len = Array.getLength(array); + + int len = Array.getLength(array); // Arr of primitives cos Java... Object[] arr = new Object[len]; for (int i = 0; i < len; i++) arr[i] = Array.get(array, i); return arr; } - + /* Others... */ /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index ffc07a6..c9ec4ba 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -56,7 +56,7 @@ public BooleanConverter() * * @since 1.3.5 */ - public BooleanConverter(boolean shorten) + public BooleanConverter(boolean shorten) { setShorten(shorten); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index b302814..0084f8e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.Instantiate; +import static org.ugp.serialx.Utils.*; import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.splitValues; @@ -193,24 +193,25 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE | getProtocolType(), args)) != null) { - Class oldObjectClass = null; + if (args.length < 6) + args = Arrays.copyOf(args, 6); + Class oldObjectClass = (Class) args[4]; + args[4] = obj.getClass(); + + int tabs = args[1] instanceof Integer ? (int) args[1] : 0; + int index = args[2] instanceof Integer ? (int) args[2] : 0; + try { - int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; - int index = args.length > 2 && args[2] instanceof Integer ? (int) args[2] : 0; - - if (args.length < 5) - args = Arrays.copyOf(args, 5); - oldObjectClass = (Class) args[4]; - args[4] = obj.getClass();; - Object[] objArgs = preferedProtocol.serialize(obj); - StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args.length > 0 ? args[0] : null, obj.getClass()) + (objArgs.length <= 0 ? "" : " ")); - + final int len = objArgs.length; + + StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args[0], obj.getClass())); args = args.clone(); - for (int i = 0, sizeEndl = 10000; i < objArgs.length; i++) + if (args[5] instanceof Byte && (byte) args[5] != 0) // Format { - if (i > 0) + for (int i = 0, sizeEndl = 10000; i < len; i++) + { if (sb.length() > sizeEndl) { sb.append('\n'); @@ -220,14 +221,26 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ } else sb.append(' '); - - if (args.length > 2) - args[2] = index + 1; - sb.append(myHomeRegistry.toString(objArgs[i], args)); + + if (args.length > 2) + args[2] = index + 1; // DO NOT TOUCH + sb.append(myHomeRegistry.toString(objArgs[i], args)); + } + } + else + { + for (int i = 0; i < len; i++) + { + sb.append(' '); + + if (args.length > 2) + args[2] = index + 1; // DO NOT TOUCH + sb.append(myHomeRegistry.toString(objArgs[i], args)); + } } args[4] = oldObjectClass; - return index > 0 && objArgs.length > 0 ? sb.insert(0, '{').append('}') : sb; + return index > 0 && len != 0 ? sb.insert(0, '{').append('}') : sb; } catch (Exception e) { @@ -242,7 +255,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ @Override public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) { - if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, '\n', '\r') != -1) + if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, ENDL) != -1) return "Multiline char sequence!"; return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE_DESERIALIZE | getProtocolType(), argsUsedConvert)).append("!"); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java index 968d64a..7ab9fdb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -38,7 +38,7 @@ public interface ImportsProvider * * @since 1.3.5 */ - public Imports getImports(); + Imports getImports(); /** * @param obj | Object to get imports from (its supposed to be instance of {@link ImportsProvider} or collection of {@link Import})! diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 3b77dd3..7ed2029 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - ${revision} + 1.3.8 \ No newline at end of file diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 047c32d..9be6c46 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-json - 1.3.8 + 1.3.9-SNAPSHOT SerialX json SerialX Json support @@ -19,7 +19,7 @@ org.ugp.serialx serialx-juss - ${revision} + 1.3.9-SNAPSHOT \ No newline at end of file diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 5e022f3..a8b5aaf 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -30,8 +30,8 @@ import org.ugp.serialx.json.converters.JsonCharacterConverter; import org.ugp.serialx.json.converters.JsonNumberConverter; import org.ugp.serialx.json.converters.JsonObjectConverter; +import org.ugp.serialx.json.converters.JsonVariableConverter; import org.ugp.serialx.juss.JussSerializer; -import org.ugp.serialx.juss.converters.VariableConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; @@ -68,7 +68,7 @@ public class JsonSerializer extends JussSerializer */ public static final String EMPTY_OBJECT = StringConverter.DirectCode("{}"); - public static final ParserRegistry JSON_PARSERS = new ParserRegistry(new VariableConverter(true), new StringConverter(), new JsonNumberConverter(), new BooleanConverter(false), new JsonCharacterConverter(false), new NullConverter(), new JsonObjectConverter()); + public static final ParserRegistry JSON_PARSERS = new ParserRegistry(new JsonVariableConverter(), new StringConverter(), new JsonNumberConverter(), new BooleanConverter(false), new JsonCharacterConverter(false), new NullConverter(), new JsonObjectConverter()); /** * @param values | Initial independent values to be added in to this scope! @@ -141,7 +141,7 @@ public JsonSerializer(Registry parsers, ProtocolRegistry protocols, @Override public String Var(String name, T value, boolean isValue) { - return Code((isValue ? "$\"" : "\"") + name + "\" = " + getParsers().toString(value, 0, 0, this, getProtocols(), isGenerateComments()) + (generateComments ? ", //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + return Code((isValue ? "$\"" : "\"") + name + "\" = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? ", //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); } @Override @@ -156,13 +156,12 @@ public Object put(String variableName, Object variableValue) public JsonSerializer emptyClone(Scope parent) { JsonSerializer srl = emptyClone(new JsonSerializer(), parent); - srl.setGenerateComments(isGenerateComments()); return srl; } @SuppressWarnings("unchecked") @Override - public S LoadFrom(Reader reader, Object... formatArgs) + public S LoadFrom(Reader reader, Object... formatArgs) throws IOException { Scope sc = super.LoadFrom(reader, formatArgs); @@ -202,7 +201,9 @@ public ParserRegistry getParsers() @Override protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException { - source.append(multilpy('\t', tabs)).append(serializedVar); + if (format != 0) + source.append(multilpy('\t', tabs)); + source.append(serializedVar); if (isLast) return source; return source.append(','); @@ -216,7 +217,9 @@ protected Appendable appandVar(Appendable source, CharSequence serializedVar, En @Override protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException { - source.append(multilpy('\t', tabs)).append(serializedVal); + if (format != 0) + source.append(multilpy('\t', tabs)); + source.append(serializedVal); if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) return source; return source.append(','); diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java new file mode 100644 index 0000000..5d45896 --- /dev/null +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java @@ -0,0 +1,19 @@ +package org.ugp.serialx.json.converters; + +import org.ugp.serialx.juss.converters.VariableConverter; + +/** + * Json specific {@link VariableConverter}. Wraps keys in "" and uses : instead of = + * + * @since 1.3.9 + */ +public class JsonVariableConverter extends VariableConverter +{ + @Override + protected StringBuilder appendEntry(StringBuilder keyString, CharSequence valueString, Object value, Object... args) + { + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + return keyString.insert(0, '"').append("\" : ").append(valueString); + return keyString.insert(0, '"').append("\":").append(valueString); + } +} diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index e1786c6..22e3218 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - ${revision} + 1.3.9-SNAPSHOT \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 93d2dd9..97ca222 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,8 +1,10 @@ package org.ugp.serialx.juss; import static org.ugp.serialx.Utils.Clone; +import static org.ugp.serialx.Utils.*; import static org.ugp.serialx.Utils.InvokeStaticFunc; import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.Utils.isOneOf; import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.converters.DataParser.VOID; @@ -89,11 +91,14 @@ public class JussSerializer extends Serializer implements ImportsProvider protected Imports imports; /** + * @deprecated (1.3.9) SET 0b10 BIT OF {@link Serializer#getFormat()} TO 1 INSTEAD IF YOU WANT TO SET THIS ON TRUE. OR SIMPLY USE {@link JussSerializer#setGenerateComments(boolean)} + * * Set this on true and program will generate comments and report!
* Note: Keep this on false to achieve the best performance! * * @since 1.0.5 */ + @Deprecated protected boolean generateComments = false; /** @@ -165,23 +170,9 @@ public JussSerializer(Registry parsers, ProtocolRegistry protocols, } @Override - public Scope clone() - { - Scope scope = super.clone(); - if (scope instanceof JussSerializer) - { - ((JussSerializer) scope).setGenerateComments(isGenerateComments()); - ((JussSerializer) scope).setParsers(getParsers()); - ((JussSerializer) scope).setProtocols(getProtocols()); - } - return scope; - } - - @Override - public JussSerializer emptyClone(Scope parent) + public JussSerializer emptyClone(Scope parent) { JussSerializer srl = emptyClone(new JussSerializer(), parent); - srl.setGenerateComments(isGenerateComments()); return srl; } @@ -209,7 +200,7 @@ public Imports getImports() public Scope clone(boolean absoluteClone) { if (absoluteClone) - return Clone(this, getParsers(), new Object[] {-9999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return Clone(this, getParsers(), new Object[] {this, -9999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); return super.clone(); } @@ -238,7 +229,7 @@ public String Var(String name, T value) */ public String Var(String name, T value, boolean isValue) { - return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), isGenerateComments()) + (generateComments ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); } /** @@ -256,13 +247,16 @@ public String StaticMember(Class cls, String staticMethodName, Object... args { StringBuilder sb = new StringBuilder(); for (int i = 0, len = args.length; i < len; i++) - sb.append(getParsers().toString(args[i], 0, 0, this, getProtocols(), isGenerateComments())).append(i < len-1 ? " " : ""); + sb.append(getParsers().toString(args[i], this, 0, 0, getProtocols(), getFormat())).append(i < len-1 ? " " : ""); return Code(cls.getName() + "::" + staticMethodName + (args.length <= 0 ? "" : " ") + sb); } /** * @param source | Source {@link Appendable} to serialize variables and objects into! - * @param args | Additional arguments to use, in case of {@link JussSerializer} this should be array of length 6 with 0. argument being this pointer to this serializer, argument 1. and 2. being integers signifying number of tabs and index of parsing iteration (used primarily by {@link ObjectConverter}), argument 3. containing {@link ProtocolRegistry} of this {@link Serializer}, argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}), and argument 5. being boolean signifying whether or not code comments are supposed to be generated! + * @param args | Additional arguments to use, in case of {@link JussSerializer} this should be array of length 6 with 0. argument being this pointer to this serializer, + * argument 1. and 2. being integers signifying number of tabs and index of parsing iteration (used primarily by {@link ObjectConverter}), argument 3. containing {@link ProtocolRegistry} of this {@link Serializer}, + * argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null), + * and argument 5. being byte bit array containing the formating flags ({@link Serializer#getFormat()}) containing the information about if the code comments are supposed to be generated and/or indentation and newline characters inclusion! * * @return Source {@link Appendable} with variables and objects serialized in specific format. * @@ -275,6 +269,7 @@ public A SerializeTo(A source, Object... args) throws IOE Map variables = variables(); List objs = values(); int valuesLen = objs.size(), varLen = variables.size(), i = 0, tabs = 0; + boolean generateComments = isGenerateComments(); if (args.length < 6) args = Arrays.copyOf(args, 6); @@ -288,7 +283,7 @@ else if (args[1] instanceof Integer) if (args[3] == null) args[3] = getProtocols(); if (args[5] == null) - args[5] = isGenerateComments(); + args[5] = getFormat(); source = source == null ? (A) new StringBuilder() : source; if (generateComments && varLen + valuesLen > 0) //Gen scope comment @@ -304,34 +299,76 @@ else if (args[1] instanceof Integer) if (tabs > -1) source.append('\n'); } - + ParserRegistry reg = getParsers(); if (varLen > 0) { - for (Entry var : variables.entrySet()) //Vars + if (generateComments) { - appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); - if (generateComments && (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty())) - GenerateComment(source, reg, var); - - if (++i < varLen || valuesLen > 0) - source.append('\n'); + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); + if (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty()) + GenerateComment(source, reg, var); + + if (++i < varLen || valuesLen > 0) + source.append('\n'); + } + } + else if (format != 0) + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); + + if (++i < varLen || valuesLen > 0) + source.append('\n'); + } + } + else // No formating + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg.toString(var, args), var, tabs, i++ >= varLen-1 && valuesLen <= 0); + } } } - for (i = 0; i < valuesLen; i++) //Values + if (generateComments) { - if (i > 0) - source.append('\n'); - - Object obj = objs.get(i); - CharSequence serialized = reg.toString(obj, args); - - appandVal(source, serialized, obj, tabs, i >= valuesLen-1); - if (generateComments && (!(obj instanceof Scope) || ((Scope) obj).isEmpty())) - GenerateComment(source, reg, obj); - } + for (i = 0; i < valuesLen; i++) //Values + { + if (i != 0) + source.append('\n'); + + Object obj = objs.get(i); + CharSequence serialized = reg.toString(obj, args); + + appandVal(source, serialized, obj, tabs, i == valuesLen-1); + if (!(obj instanceof Scope) || ((Scope) obj).isEmpty()) + GenerateComment(source, reg, obj); + } + } + else if (format != 0) + { + for (i = 0; i < valuesLen; i++) //Values + { + if (i != 0) + source.append('\n'); + + Object obj; + appandVal(source, reg.toString(obj = objs.get(i), args), obj, tabs, i == valuesLen-1); + } + } + else // No formating + { + for (i = 0; i < valuesLen; i++) //Values + { + Object obj; + appandVal(source, reg.toString(obj = objs.get(i), args), obj, tabs, i == valuesLen-1); + } + } if (source instanceof Flushable) ((Flushable) source).flush(); @@ -347,8 +384,10 @@ else if (args[1] instanceof Integer) */ protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException { - source.append(multilpy('\t', tabs)).append(serializedVar); - if (isLast && var.getValue() instanceof Scope) + if (format != 0) + source.append(multilpy('\t', tabs)); + source.append(serializedVar); + if (isLast) return source; return source.append(';'); } @@ -360,8 +399,10 @@ protected Appendable appandVar(Appendable source, CharSequence serializedVar, En */ protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException { - source.append(multilpy('\t', tabs)).append(serializedVal); - if (isLast && value instanceof Scope || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) + if (format != 0) + source.append(multilpy('\t', tabs)); + source.append(serializedVal); + if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) return source; return source.append(';'); } @@ -388,7 +429,9 @@ public Appendable GenerateComment(Appendable source, ParserRegistry registry, Ob /** * @param reader | Reader to read from! - * @param args | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this scope (it can be also boolean signifying if formating is required), 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, and additional argument 4. being of type {@link Class} containing information about class that is curently being serialized (used primarily by {@link ObjectConverter}). + * @param args | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this serializer, + * 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, + * and additional argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null). * * @return This scope after loading data from reader (you most likely want to return "this")! * @@ -404,157 +447,174 @@ public S LoadFrom(Reader reader, Object... args) throws IOExce if (args.length < 4) args = Arrays.copyOf(args, 4); - if (args[0] instanceof Boolean) - formatRequired = (boolean) args[0]; +// if (args[0] instanceof Boolean) +// formatRequired = (boolean) args[0]; args[0] = this; if (args[3] == null) args[3] = getProtocols(); - StringBuilder str = readAndFormat(reader, formatRequired); // TODO could be improved... + StringBuilder str = readAndFormat(reader, formatRequired); List objs = splitAndParse(str, args); addAll(objs); +// readAndParse(values(), reader, 512, args); + if (parent == null) getImports().removeImportsOf(this); return (S) this; } - public void readAndParse(Reader reader) throws IOException + /** + * @param result | Resulting collection of objects to fill up with parsed objects from reader. + * @param reader | The reader to {@link Reader#read(char[], int, int)}. + * @param charBuffLen | Length of internal char buffer (number of chars that are processed at once). Recommended length is 512, in case of increase should be the power of 2. + * @param parserArgs | Additional arguments to use. Take a look at {@link Serializer#LoadFrom(File, Object...)}. + * + * @throws IOException If {@link Reader} instance throws it during reading... + * + * @since 1.3.9 + */ + public void readAndParse(Collection result, Reader reader, final int charBuffLen, Object... parserArgs) throws IOException { - final char endl = System.lineSeparator().charAt(0); - -// StringBuilder str = readAndFormat(reader, formatRequired); // TODO could be improved... -// List objs = splitAndParse(str, args); -// addAll(objs); + ParserRegistry reg = getParsers(); StringBuilder sb = new StringBuilder(); - char[] chars = new char[128*2]; - - for (int charsRead, oldCh = 0, state = 0, brackets; (charsRead = reader.read(chars)) != -1; ) + int len; + + char chars[] = new char[charBuffLen], oldCh = 0; + readerLoop: for (int charsRead, /*state = 0,*/ brackets; (charsRead = reader.read(chars, 0, charBuffLen)) != -1; ) { - int i = 0; - switch (state) // Complete the unfinished action from prev iter based on state // <- Too much repetitive code already, and pain in the ass to work around with, consider other solution + charsLoop: for (int i = 0; i < charsRead; i++) { - case '/': // Handle ongoing comments... - do if (chars[i] == endl) // Skip all until endl - { - oldCh = state = 0; - i++; - break; - } - while (++i < charsRead); - - break; - case '*': - do if (chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/') // Skip all until */ - { - oldCh = state = 0; - i++; - break; - } - while (++i < charsRead); - - break; - - case '\"': - case '\'': - do // Append all chars until end of str/char - { - char ch; - sb.append(ch = chars[i]); - if (ch == state) - { - state = 0; - i++; - break; - } - } - while (++i < charsRead); - - break; -// case ' ': -// do if (chars[i] > 32) // Skip all blanks until next non-blank -// { -// state = 0; -// //i++; -// break; -// } -// while (++i < charsRead); -// -// break; - } - - charsLoop: for (; i < charsRead; i++) - { - int ch = chars[i]; - if (ch < 33) // Handle blanks, skip unnecessary - { - if (oldCh > 32) // First blank (in possible row) - sb.append(oldCh /*= state*/ = ' '); - continue; - } + char ch = chars[i]; if (oldCh == '/') // Skip the comments... { - if (ch == '/') // // - { - for (state = '/'; ++i < charsRead; ); // Skip all until endl - if (chars[i] == endl) - { - oldCh = state = 0; - continue charsLoop; - } - } - else if (ch == '*') // /* + if (ch == '/' || ch == '*') // // | /* { - for (state = '*'; ++i < charsRead; ) // Skip all until */ - if (chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/') // */ - { - oldCh = state = 0; + sb.setLength(len = (sb.length() - 1)); // Pop / and restore old char, important! + oldCh = len == 0 ? 0 : sb.charAt(len - 1); + for (;;) // Skip all till end of comm + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + if (ch == '/' ? + isOneOf(chars[i], ENDL) : + chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/' // */ + ) { continue charsLoop; } + } } - - continue; } if (ch == '\"' || ch == '\'') { sb.append(ch); - for (state = ch; ++i < charsRead; ) // Append all chars until end of str/char + for (oldCh = ch; ; ) // Append all chars until end of str/char { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + sb.append(ch = chars[i]); - if (ch == state) - { - state = 0; - break; - } + if (ch == oldCh) + continue charsLoop; // break; } } else if ((ch | ' ') == '{') { - for (brackets = 1; ++i < charsRead && brackets != 0; ) + sb.append(ch); + brackets = 1; + do { - if ((ch = (chars[i] | ' ')) == '{') + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + sb.append(ch = chars[i]); + if ((ch |= ' ') == '{') brackets++; else if (ch == '}') brackets--; - else if (ch == '"') - while (++i < charsRead && chars[i] != '"'); + else if (ch == '\"' || ch == '\'') + { + for (oldCh = ch; ; ) // Append all chars until end of str/char + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + sb.append(ch = chars[i]); + if (ch == oldCh) + break; + } + } + } + while (brackets != 0); + } + else if (ch == ';' || ch == ',' || (oldCh == '}' && isOneOf(ch, ENDL))) + { + if ((len = sb.length()) != 0) + { + if (oldCh == ' ') // Trim + sb.setLength(--len); + + if (len != 0) + { +// System.err.println("|" + sb.toString() + "| " + (oldCh == ' ') + "\n"); + Object obj = parseObject(reg, sb.toString(), parserArgs); + if (obj != VOID) + result.add(obj); + sb.setLength(0); + } } + + oldCh = 0; + continue; } + else if (ch <= ' ') // Handle blanks, skip unnecessary + { + if (oldCh > ' ') // First blank (in possible row) + sb.append(oldCh /*= state*/ = ' '); + continue; + } + else + sb.append(ch); oldCh = ch; } } + if ((len = sb.length()) == 0) + return; + + if (oldCh == ' ') // Trim + sb.setLength(--len); + + if (len != 0) + { +// System.err.println("|" + sb.toString() + "| " + (oldCh) + "\n"); + Object obj = parseObject(reg, sb.toString(), parserArgs); + if (obj != VOID) + result.add(obj); + } } /** + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, Object...)} INSTEAD! + * * @return Formated content of reader ready to parse! Should not modify this object in any way! * * @since 1.3.2 */ + @Deprecated public StringBuilder readAndFormat(Reader reader, boolean format) { int quote = 0, multLineCom = -1; @@ -636,10 +696,13 @@ else if (ch == '}' || ch == ']') } /** + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, Object...)} INSTEAD! + * * @return List of objects parsed from given formatted string! * * @since 1.3.2 */ + @Deprecated public List splitAndParse(StringBuilder formattedStr, Object... parserArgs) { List result = new ArrayList<>(); @@ -675,9 +738,9 @@ else if (ch == '"') else if ((ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) { String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); - System.out.println(str + "\n"); if (!str.isEmpty()) { +// System.out.println("|" + str + "|\n"); Object obj = parseObject(reg, str, parserArgs); if (obj != VOID) result.add(obj); @@ -687,9 +750,9 @@ else if (ch == '"') } String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); - System.out.println(str + "\n"); if (!str.isEmpty()) { +// System.out.println("|" + str + "|\n"); Object obj = parseObject(reg, str, parserArgs); if (obj != VOID) result.add(obj); @@ -754,7 +817,7 @@ public T cloneOf(String variableKey, T defaultValue) T obj = get(variableKey, defaultValue); if (obj == defaultValue) return defaultValue; - return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); } /** @@ -770,7 +833,7 @@ public T cloneOf(String variableKey, T defaultValue) public T cloneOf(int valueIndex) { T obj = get(valueIndex); - return Clone(obj, getParsers(), new Object[] {-99999, 0, this, getProtocols(), isGenerateComments()}, this, null, null, getProtocols()); + return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); } /** @@ -780,7 +843,7 @@ public T cloneOf(int valueIndex) */ public boolean isGenerateComments() { - return generateComments; + return (format & 0b10) != 0; } /** @@ -790,7 +853,10 @@ public boolean isGenerateComments() */ public void setGenerateComments(boolean generateComments) { - this.generateComments = generateComments; + if (generateComments) + format |= 0b10; + else + format &= 0xff ^ 0b10; } // /** diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index a71e0d3..584d913 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -94,37 +94,60 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. if (index <= 0 || myHomeRegistry.indexOf(OperationGroups.class) > -1) { - int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; + int tabs; if (args.length > 2) { + tabs = args[1] instanceof Integer ? (int) args[1] : 0; + args = args.clone(); //Necessary for preventing this from affecting other objects and arrays... args[2] = index + 1; } + else + tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; Object[] elms = fromAmbiguousArray(obj); + final int len = elms.length; StringBuilder sb = new StringBuilder(); - for (int i = 0, length = elms.length, sizeEndl = 10000; i < length; i++) + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) // Format { - if (i > 0) - if (sb.length() > sizeEndl) - { - sb.append('\n'); - for (int j = 0; j < tabs+1; j++) - sb.append('\t'); - sizeEndl += 10000; - } - else + for (int i = 0, sizeEndl = 10000; i < len; i++) + { + if (i != 0) + if (sb.length() > sizeEndl) + { + sb.append('\n'); + for (int j = 0; j < tabs+1; j++) + sb.append('\t'); + sizeEndl += 10000; + } + else + sb.append(' '); + + CharSequence str = myHomeRegistry.toString(elms[i], args); + char ch = str.charAt(0); + if ((ch | ' ') == '{') + sb.append('(').append(str).append(')'); + else + sb.append(str); + } + } + else + { + for (int i = 0; i < len; i++) + { + if (i != 0) sb.append(' '); - - CharSequence str = myHomeRegistry.toString(elms[i], args); - char ch = str.charAt(0); - if ((ch | ' ') == '{') - sb.append('(').append(str).append(')'); - else - sb.append(str); - + + CharSequence str = myHomeRegistry.toString(elms[i], args); + char ch = str.charAt(0); + if ((ch | ' ') == '{') + sb.append('(').append(str).append(')'); + else + sb.append(str); + } } + return index > 0 ? sb.insert(0, '(').append(')') : sb; } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index ebcf6cd..8296c0f 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -153,6 +153,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. * @since 1.3.5 */ @SuppressWarnings("unchecked") + @Override public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { if (obj instanceof Scope) @@ -171,19 +172,21 @@ else if (args.length > 0 && args[0] instanceof Serializer) { serializer = getPreferredSerializer(); } - - if (serializer instanceof JussSerializer) - ((JussSerializer) serializer).setGenerateComments(args.length > 5 && args[5] instanceof Boolean && (boolean) args[5]); + if (args.length < 6) + args = Arrays.copyOf(args, 6); + else + { + if (args[5] instanceof Byte) + serializer.setFormat((byte) args[5]); + + args = args.clone(); + } + args[2] = 0; + args[3] = serializer.getProtocols(); + try { - if (args.length < 4) - args = Arrays.copyOf(args, 4); - else - args = args.clone(); - args[2] = 0; - args[3] = serializer.getProtocols(); - StringBuilder sb = new StringBuilder(); GenericScope parent; if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 065248a..ecc5051 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,7 +1,6 @@ package org.ugp.serialx.juss.converters; import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.Utils.splitValues; import java.util.AbstractMap; @@ -11,6 +10,7 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.VariableParser; /** @@ -28,6 +28,7 @@ */ public class VariableConverter extends VariableParser implements DataConverter { + @Deprecated protected boolean jsonStyle; public VariableConverter() @@ -36,10 +37,14 @@ public VariableConverter() } /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! * * @since 1.3.2 */ + @Deprecated public VariableConverter(boolean jsonStyle) { setJsonStyle(jsonStyle); @@ -91,7 +96,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) if ((op0Index = var.indexOf('.')) > -1) { - String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); + String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); int iLast = path.length-1, j = 0; backlook: do @@ -132,16 +137,37 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. if (obj instanceof Entry) { Entry var = (Entry) obj; - int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; - - boolean jsonStyle = isJsonStyle(), genericVar; - Object key = (genericVar = !((key = var.getKey()) instanceof String)) ? myHomeRegistry.toString(key, args) : key, val = var.getValue(); - return new StringBuilder().append(jsonStyle && !genericVar ? "\""+key+"\"" : key) - .append(val instanceof GenericScope && !((GenericScope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")) - .append(myHomeRegistry.toString(val, args)); + + final Object key, val = var.getValue(); + return appendEntry(new StringBuilder((key = var.getKey()) instanceof String ? + (String) key : + myHomeRegistry.toString(key, args) + ), myHomeRegistry.toString(val, args), val, args); } return CONTINUE; } + + /** + * @param keyString | The string builder containing the key as string. + * @param valueString | The string containing the serialized value. + * @param value | The real value, the valueString before it was serialized... + * @param args | Same as {@link DataParser#parse(org.ugp.serialx.converters.DataParser.ParserRegistry, String, Object...)} + * + * @return Should return the string form of an entry (key value pair). Preferably constructed by appending some form of assignment operator (such as =) to the keyString and then appending the valueString at the end with some formating around it if needed. + * No unrelated characters should be included! + * + * @since 1.3.9 + */ + protected StringBuilder appendEntry(StringBuilder keyString, CharSequence valueString, Object value, Object... args) + { +// int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; +// return sb +// .append(val instanceof GenericScope && !((GenericScope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")) +// .append(myHomeRegistry.toString(val, args)); + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + return keyString.append(" = ").append(valueString); + return keyString.append("=").append(valueString); + } @SuppressWarnings("unchecked") @Override @@ -176,20 +202,28 @@ public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, St } /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * * @return True if variables will be serialized using json style ("key" : value)! * * @since 1.3.2 */ + @Deprecated public boolean isJsonStyle() { return jsonStyle; } /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! * * @since 1.3.2 */ + @Deprecated public void setJsonStyle(boolean jsonStyle) { this.jsonStyle = jsonStyle; @@ -225,21 +259,14 @@ else if (ch == '"') while (++i < len && s.charAt(i) != '"'); } } - else if ((ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) + else if ((ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) return i; oldCh = ch; } return -1; } - -// public static V getValueOf(GenericScope scope, K... pathToScope) -// { -// -// if (scope.containsVariable(pathToScope[0])) -// return scope.getGenericScope(pathToScope); -// } - + /** * @param varName | Name of variable. * @param varValue | Value of variable. diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index c28998b..c7f9b69 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - ${revision} + 1.3.9-SNAPSHOT \ No newline at end of file diff --git a/pom.xml b/pom.xml index 7abb0bd..3b019da 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 8 - 1.3.8 + 1.3.9-SNAPSHOT UTF-8 ${java.version} From 527f6cd67bbd6e8e1259a1b15f442688fee25cf7 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 9 Jul 2025 00:35:18 +0200 Subject: [PATCH 51/75] removing deprecateds --- .../java/org/ugp/serialx/GenericScope.java | 15 ------- .../main/java/org/ugp/serialx/Serializer.java | 4 ++ .../src/main/java/org/ugp/serialx/Utils.java | 30 -------------- .../serialx/converters/NumberConverter.java | 41 ------------------- .../org/ugp/serialx/json/JsonSerializer.java | 1 + .../org/ugp/serialx/juss/JussSerializer.java | 7 ++++ .../juss/converters/OperationGroups.java | 10 ----- .../operators/ArithmeticOperators.java | 33 --------------- 8 files changed, 12 insertions(+), 129 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 1e4ef01..d7b0a30 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -378,21 +378,6 @@ public boolean contains(Object value) return values().contains(value); } - /** - * @deprecated USE {@link GenericScope#contains(Object)} instead! - * - * @param value | Object the value. - * - * @return True if independent value was found in this scope. - * - * @since 1.2.0 - */ - @Deprecated - public boolean containsIndependentValue(ValT value) - { - return values().contains(value); - } - /** * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! * {@link IndexOutOfBoundsException} will be thrown if index is too big! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 1f55ed1..7565100 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -25,6 +25,7 @@ import java.net.URI; import java.net.URL; import java.net.URLConnection; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -198,6 +199,8 @@ public T into(T obj, String... fieldNamesToUse) throws IntrospectionExceptio } /** + * @deprecated (1.3.9) DO NOT USE THIS, USE VARIATION OF {@link AbstractMap.SimpleEntry} OR {@link VariableConverter#NewVariable(String, Object)} FROM serialx-juss module INSTEAD! + * * @param name | Name of variable. * @param value | Value of variable. * @@ -205,6 +208,7 @@ public T into(T obj, String... fieldNamesToUse) throws IntrospectionExceptio * * @since 1.1.5 */ + @Deprecated public String Var(String name, T value) { return Code(name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), false) + ";"); diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 2d7d01e..8797639 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -932,34 +932,4 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO conn.setDoOutput(true); conn.getOutputStream().write(postDataBytes); } - - /** - * This is a "dummy" class that {@link Serializer} uses internally as an OOP programmatic interpretation of null. In otherwise this is wrapper object for null. - * Note: You should not be able to come in contact with this during serialization and loading, if you did then you most likely encountered and bug and you should report it! - * - * @author PETO - * - * @since 1.2.2 - * - * @deprecated (in 1.3.8) NO LONGER NEEDED, DO NOT USE THIS! You were never supposed to... - */ - public static final class NULL //TODO: REMOVE IN NEXT V!!!! - { - public static Object toOopNull(Object obj) - { - return obj == null ? new NULL() : obj; - } - - @Override - public boolean equals(Object obj) - { - return obj == null || obj instanceof NULL; - } - - @Override - public String toString() - { - return "NULL"; - } - } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 2b4a998..5378cc8 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -1,11 +1,6 @@ package org.ugp.serialx.converters; import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.fastReplace; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.Locale; /** * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! @@ -93,19 +88,6 @@ new Double(0.1e2) */ public class NumberConverter implements DataConverter { - /** - * {@link DecimalFormat} to format decimal numbers (double, float) during serialization!
- * Default {@link DecimalFormat} will round decimal numbers to 3 decimal places (format pattern #.###)! - * - * Set this on null and decimal numbers will not be formated! Do this when you need accuracy! - * - * @serial 1.1.0 (moved to {@link NumberConverter} since 1.3.0) - * - * @deprecated DO NOT USE! Override {@link NumberConverter#format(Object)} and write your format logic there instead! - */ - @Deprecated - public static DecimalFormat decimalFormatter = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US)); - @Override public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) { @@ -257,27 +239,4 @@ else if (ch != 127 && ch != '+') return (byte) result; return (int) result; } - - /** - * @deprecated THIS IS OBSOLET, SLOW AND NO LONGER NECESSARY BECAUSE {@link NumberConverter#numberOf(CharSequence, char, int, int, int)} CAN DO THE SAME THING MUCH FASTET! - * - * @param num | Number string to format! - * - * @return Original string with formated sign and deleted '_'! - * - * @since 1.3.0 - */ - @Deprecated - public static String normFormatNum(String num) - { - if (num.length() > 2) - for (boolean minus = num.startsWith("+-") || num.startsWith("-+"); minus || num.startsWith("++") || num.startsWith("--"); minus = num.startsWith("+-") || num.startsWith("-+")) - { - num = num.substring(2); - if (minus) - num = "-"+num; - } - - return fastReplace(num, "_", ""); - } } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index a8b5aaf..45c3d85 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -138,6 +138,7 @@ public JsonSerializer(Registry parsers, ProtocolRegistry protocols, super(parsers, protocols, variablesMap, values, parent); } + @Deprecated @Override public String Var(String name, T value, boolean isValue) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 97ca222..5d5f55b 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -19,6 +19,7 @@ import java.net.URL; import java.net.URLConnection; import java.text.SimpleDateFormat; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -205,6 +206,8 @@ public Scope clone(boolean absoluteClone) } /** + * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! + * * @param name | Name of variable. * @param value | Value of variable. * @@ -212,6 +215,7 @@ public Scope clone(boolean absoluteClone) * * @since 1.1.5 */ + @Deprecated @Override public String Var(String name, T value) { @@ -219,6 +223,8 @@ public String Var(String name, T value) } /** + * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! + * * @param name | Name of variable. * @param value | Value of variable. * @param isValue | True if variables value supposed to by visible also during value loading. @@ -227,6 +233,7 @@ public String Var(String name, T value) * * @since 1.1.5 */ + @Deprecated public String Var(String name, T value, boolean isValue) { return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 9a95205..bce74f9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -25,16 +25,6 @@ */ public class OperationGroups implements DataParser { - /** - * @deprecated (since 1.3.8) DO NOT USE, USE {@link OperationGroups#groupMark} instead!
- * - * Opening and closing of group mark! - * - * @since 1.3.0 - */ - @Deprecated - public static final char[] GROUP_MARK_OP = new char[] {127, 128, 129}, GROUP_MARK_CLS = new char[] {129, 128, 127}; - /** * Character marking the opening of {@link OperationGroups} mark in processed string, closing should be marked as this character -1.
* This character is generated in sami-random fashion but it will never be an ASCII character. diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 47dd813..1845902 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -22,12 +22,6 @@ */ public class ArithmeticOperators implements DataParser { - /** - * @deprecated DO NOT USE! USE {@link ArithmeticOperators#operator(Object, String, Object)} AND {@link ArithmeticOperators#getOperatorPriority(String)} INSTEAD! - */ - @Deprecated - protected String[] priority1Oprs = {"*", "*-", "/", "/-", "%"}, priority2Oprs = {"**", "**-"}; - /** * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator(Object, String, Object)}.
Intended for override, should not be null or empty! * @@ -514,31 +508,4 @@ public static Object toNum(Object obj) return (int) (char) obj; return obj; } - - /** - * @deprecated THIS WAS QUIET A MESSY WORKAROUND, DO NOT USE!
- * - * Used internally by {@link ArithmeticOperators} to wrap result of evaluation! - * Mainly used by String results! - * - * @author PETO - * - * @since 1.3.0 - */ - @Deprecated - protected static class ResultWrapper - { - public final Object obj; - - public ResultWrapper(Object obj) - { - this.obj = obj; - } - - @Override - public String toString() - { - return obj.toString(); - } - } } From 006e5517a1520ca615a1eaf791ce93af3dcecd8e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 9 Jul 2025 23:05:23 +0200 Subject: [PATCH 52/75] changing naming of legacy Serializer methods (S -> s), finally... --- .../main/java/org/ugp/serialx/Serializer.java | 112 +++++++++--------- .../org/ugp/serialx/json/JsonSerializer.java | 30 ++--- .../org/ugp/serialx/juss/JussSerializer.java | 34 +++--- .../juss/converters/ObjectConverter.java | 4 +- 4 files changed, 91 insertions(+), 89 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 7565100..9ee2fb7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -252,12 +252,12 @@ public String Code(Object code) * * @since 1.3.2 * - * @see Serializer#Stringify(Object...) + * @see Serializer#stringify(Object...) */ public String toString(boolean serialize) throws IOException { if (serialize) - return Stringify(); + return stringify(); return super.toString(); } @@ -271,9 +271,9 @@ public String toString(boolean serialize) throws IOException * * @since 1.1.5 */ - public void SerializeTo(File f, Object... args) throws IOException + public void serializeTo(File f, Object... args) throws IOException { - SerializeTo(false, f, args); + serializeTo(false, f, args); } /** @@ -287,18 +287,18 @@ public void SerializeTo(File f, Object... args) throws IOException * * @since 1.1.5 * - * @see Serializer#SerializeTo(Appendable, Object...) + * @see Serializer#serializeTo(Appendable, Object...) */ - public void SerializeTo(boolean append, File f, Object... args) throws IOException + public void serializeTo(boolean append, File f, Object... args) throws IOException { //double t0 = System.nanoTime(); Writer writer = new BufferedWriter(new FileWriter(f, append)); - writer.write(Stringify(args)); + writer.write(stringify(args)); writer.close(); -// String serialized = Stringify(args); +// String serialized = stringify(args); // // RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); // FileChannel channel = fileOutputStream.getChannel(); @@ -320,11 +320,11 @@ public void SerializeTo(boolean append, File f, Object... args) throws IOExcepti * * @since 1.0.0 * - * @see Serializer#SerializeTo(Appendable, Object...) + * @see Serializer#serializeTo(Appendable, Object...) */ - public String Stringify(Object... args) throws IOException + public String stringify(Object... args) throws IOException { - return SerializeTo(new StringBuilder(), args).toString(); + return serializeTo(new StringBuilder(), args).toString(); } /** @@ -335,11 +335,11 @@ public String Stringify(Object... args) throws IOException * * @since 1.3.2 * - * @see Serializer#SerializeTo(Appendable, Object...) + * @see Serializer#serializeTo(Appendable, Object...) */ - public OutputStream SerializeTo(OutputStream outputStream, Object... args) throws IOException + public OutputStream serializeTo(OutputStream outputStream, Object... args) throws IOException { - SerializeTo(new OutputStreamWriter(outputStream), args); + serializeTo(new OutputStreamWriter(outputStream), args); return outputStream; } @@ -351,7 +351,7 @@ public OutputStream SerializeTo(OutputStream outputStream, Object... args) throw * * @since 1.3.2 */ - public abstract A SerializeTo(A source, Object... args) throws IOException; + public abstract A serializeTo(A source, Object... args) throws IOException; /** * @param file | Text file with serialized objects in specific format to load. @@ -364,11 +364,11 @@ public OutputStream SerializeTo(OutputStream outputStream, Object... args) throw * * @since 1.0.0 * - * @see Serializer#LoadFrom(Reader, Object...) + * @see Serializer#loadFrom(Reader, Object...) */ - public S LoadFrom(File file, Object... parserArgs) throws IOException + public S loadFrom(File file, Object... parserArgs) throws IOException { - return LoadFrom(new FileReader(file), parserArgs); + return loadFrom(new FileReader(file), parserArgs); } /** @@ -382,11 +382,11 @@ public S LoadFrom(File file, Object... parserArgs) throws IOEx * * @since 1.2.5 * - * @see Serializer#LoadFrom(Reader, Object...) + * @see Serializer#loadFrom(Reader, Object...) */ - public S LoadFrom(CharSequence str, Object... parserArgs) throws IOException + public S loadFrom(CharSequence str, Object... parserArgs) throws IOException { - return LoadFrom(new StringReader(str.toString()), parserArgs); + return loadFrom(new StringReader(str.toString()), parserArgs); } /** @@ -400,11 +400,11 @@ public S LoadFrom(CharSequence str, Object... parserArgs) thro * * @since 1.3.2 * - * @see Serializer#LoadFrom(Reader, Object...) + * @see Serializer#loadFrom(Reader, Object...) */ - public S LoadFrom(InputStream stream, Object... parserArgs) throws IOException + public S loadFrom(InputStream stream, Object... parserArgs) throws IOException { - return LoadFrom(new InputStreamReader(stream), parserArgs); + return loadFrom(new InputStreamReader(stream), parserArgs); } /** @@ -416,9 +416,9 @@ public S LoadFrom(InputStream stream, Object... parserArgs) th * * @since 1.2.5 */ - public S LoadFrom(Reader reader) throws IOException + public S loadFrom(Reader reader) throws IOException { - return LoadFrom(reader, true); + return loadFrom(reader, true); } /** @@ -431,7 +431,7 @@ public S LoadFrom(Reader reader) throws IOException * * @since 1.3.2 */ - public abstract S LoadFrom(Reader reader, Object... parserArgs) throws IOException; + public abstract S loadFrom(Reader reader, Object... parserArgs) throws IOException; /** * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! @@ -613,9 +613,9 @@ public Object apply(Object t) * * @since 1.3.5 */ - public A SerializeAsSubscope(A source, Object... args) throws IOException + public A serializeAsSubscope(A source, Object... args) throws IOException { - return SerializeAsSubscope(source, new char[] {'{', '}'}, args); + return serializeAsSubscope(source, new char[] {'{', '}'}, args); } /** @@ -628,7 +628,7 @@ public A SerializeAsSubscope(A source, Object... args) th * @since 1.3.5 */ @SuppressWarnings("unchecked") - public A SerializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException + public A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException { source.append(wrappingBrackets[0]); if (isEmpty()) @@ -638,7 +638,7 @@ public A SerializeAsSubscope(A source, final char[] wrapp { if (args.length > 1 && args[1] instanceof Integer) args[1] = ((int) args[1]) + 1; - return (A) SerializeTo(source, args).append(wrappingBrackets[1]); + return (A) serializeTo(source, args).append(wrappingBrackets[1]); } int tabs; @@ -647,7 +647,7 @@ public A SerializeAsSubscope(A source, final char[] wrapp else tabs = 0; - return (A) SerializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)) + return (A) serializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)) .append(wrappingBrackets[1]); } @@ -681,7 +681,7 @@ public T getParsed(String variableWithStringValue, Object... args) /** * @return Non 0 value if proper indentation and newline characters should be used when serializing. Default is 0, no formating... - * The exact behavior of other values will depend on the specific implementation of {@link Serializer#SerializeTo(Appendable, Object...)} + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} * * @since 1.3.9 */ @@ -692,7 +692,7 @@ public byte getFormat() /** * @param format | A non 0 value if proper indentation and newline characters should be used when serializing. - * The exact behavior of other values will depend on the specific implementation of {@link Serializer#SerializeTo(Appendable, Object...)} + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} * * @since 1.3.9 */ @@ -721,15 +721,15 @@ public void setFormat(byte format) {@link File} - {@link Serializer#SerializeTo(File)} + {@link Serializer#serializeTo(File)} {@link Appendable} - {@link Serializer#SerializeTo(Appendable, Object...)} + {@link Serializer#serializeTo(Appendable, Object...)} {@link OutputStream} - {@link Serializer#SerializeTo(OutputStream, Object...)} + {@link Serializer#serializeTo(OutputStream, Object...)} {@link URL} @@ -759,19 +759,19 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN { if (obj instanceof File) { - fromSerializer.SerializeTo((File) obj); + fromSerializer.serializeTo((File) obj); return (T) obj; } if (obj instanceof Appendable) { - fromSerializer.SerializeTo((Appendable) obj); + fromSerializer.serializeTo((Appendable) obj); return (T) obj; } if (obj instanceof OutputStream) { - fromSerializer.SerializeTo((OutputStream) obj); + fromSerializer.serializeTo((OutputStream) obj); return (T) obj; } @@ -782,7 +782,7 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN if (con instanceof HttpURLConnection) post(fromSerializer, (HttpURLConnection) con); else - fromSerializer.SerializeTo(con.getOutputStream()); + fromSerializer.serializeTo(con.getOutputStream()); return (T) con; } @@ -791,7 +791,7 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN if (obj instanceof HttpURLConnection) post(fromSerializer, (HttpURLConnection) obj); else - fromSerializer.SerializeTo(((URLConnection) obj).getOutputStream()); + fromSerializer.serializeTo(((URLConnection) obj).getOutputStream()); return (T) obj; } @@ -806,14 +806,14 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN if (con instanceof HttpURLConnection) post(fromSerializer, (HttpURLConnection) con); else - fromSerializer.SerializeTo(con.getOutputStream()); + fromSerializer.serializeTo(con.getOutputStream()); return (T) con; } try { File file = new File(obj.toString()); - fromSerializer.SerializeTo(file); + fromSerializer.serializeTo(file); return (T) file; } catch (Exception e) @@ -846,7 +846,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence, Object...)} + {@link Serializer#loadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -854,15 +854,15 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File, Object...)} + {@link Serializer#loadFrom(File, Object...)} {@link Reader} - {@link Serializer#LoadFrom(Reader)} + {@link Serializer#loadFrom(Reader)} {@link InputStream} - {@link Serializer#LoadFrom(InputStream, Object...)} + {@link Serializer#loadFrom(InputStream, Object...)} {@link URL} @@ -892,8 +892,8 @@ public static Serializer from(Serializer newInstance, Object fromObj, String... { String fromStr; if (indexOfNotInObj(fromStr = fromObj.toString(), "http") == 0) - return newInstance.LoadFrom(new URI(fromStr).toURL().openStream()); - return newInstance.LoadFrom(new File(fromStr)); + return newInstance.loadFrom(new URI(fromStr).toURL().openStream()); + return newInstance.loadFrom(new File(fromStr)); } catch (Exception e) { @@ -901,19 +901,19 @@ public static Serializer from(Serializer newInstance, Object fromObj, String... throw e; } - return newInstance.LoadFrom((CharSequence) fromObj); + return newInstance.loadFrom((CharSequence) fromObj); } if (fromObj instanceof File) - return newInstance.LoadFrom((File) fromObj); + return newInstance.loadFrom((File) fromObj); if (fromObj instanceof Reader) - return newInstance.LoadFrom((Reader) fromObj); + return newInstance.loadFrom((Reader) fromObj); if (fromObj instanceof InputStream) - return newInstance.LoadFrom((InputStream) fromObj); + return newInstance.loadFrom((InputStream) fromObj); if (fromObj instanceof URL) - return newInstance.LoadFrom(((URL) fromObj).openStream()); + return newInstance.loadFrom(((URL) fromObj).openStream()); if (fromObj instanceof URLConnection) - return newInstance.LoadFrom(((URLConnection) fromObj).getInputStream()); + return newInstance.loadFrom(((URLConnection) fromObj).getInputStream()); newInstance.addAll(Scope.from(fromObj, fieldNamesToUse)); return newInstance; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 45c3d85..ab8cb09 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -162,9 +162,9 @@ public JsonSerializer emptyClone(Scope parent) @SuppressWarnings("unchecked") @Override - public S LoadFrom(Reader reader, Object... formatArgs) throws IOException + public S loadFrom(Reader reader, Object... formatArgs) throws IOException { - Scope sc = super.LoadFrom(reader, formatArgs); + Scope sc = super.loadFrom(reader, formatArgs); if (formatArgs.length > 0 && formatArgs[0] instanceof Serializer) return (S) sc; @@ -175,7 +175,7 @@ public S LoadFrom(Reader reader, Object... formatArgs) throws } @Override - public A SerializeTo(A source, Object... args) throws IOException + public A serializeTo(A source, Object... args) throws IOException { int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; @@ -183,9 +183,9 @@ public A SerializeTo(A source, Object... args) throws IOE { JussSerializer scope = emptyClone(null); scope.add(this); - return scope.SerializeTo(source, args); + return scope.serializeTo(source, args); } - return super.SerializeTo(source, args); + return super.serializeTo(source, args); } @Override @@ -227,9 +227,9 @@ protected Appendable appandVal(Appendable source, CharSequence serializedVal, Ob } @Override - public A SerializeAsSubscope(A source, Object... args) throws IOException + public A serializeAsSubscope(A source, Object... args) throws IOException { - return SerializeAsSubscope(source, variablesCount() > 0 ? new char[] {'{', '}'} : new char[] {'[', ']'}, args); + return serializeAsSubscope(source, variablesCount() > 0 ? new char[] {'{', '}'} : new char[] {'[', ']'}, args); } /** @@ -300,7 +300,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence, Object...)} + {@link Serializer#loadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -308,15 +308,15 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File, Object...)} + {@link Serializer#loadFrom(File, Object...)} {@link Reader} - {@link Serializer#LoadFrom(Reader)} + {@link Serializer#loadFrom(Reader)} {@link InputStream} - {@link Serializer#LoadFrom(InputStream, Object...)} + {@link Serializer#loadFrom(InputStream, Object...)} {@link URL} @@ -367,7 +367,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence, Object...)} + {@link Serializer#loadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -375,15 +375,15 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File, Object...)} + {@link Serializer#loadFrom(File, Object...)} {@link Reader} - {@link Serializer#LoadFrom(Reader)} + {@link Serializer#loadFrom(Reader)} {@link InputStream} - {@link Serializer#LoadFrom(InputStream, Object...)} + {@link Serializer#loadFrom(InputStream, Object...)} {@link URL} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 5d5f55b..8ca7696 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -271,7 +271,7 @@ public String StaticMember(Class cls, String staticMethodName, Object... args */ @SuppressWarnings("unchecked") @Override - public A SerializeTo(A source, Object... args) throws IOException + public A serializeTo(A source, Object... args) throws IOException { Map variables = variables(); List objs = values(); @@ -448,9 +448,9 @@ public Appendable GenerateComment(Appendable source, ParserRegistry registry, Ob */ @SuppressWarnings("unchecked") @Override - public S LoadFrom(Reader reader, Object... args) throws IOException + public S loadFrom(Reader reader, Object... args) throws IOException { - boolean formatRequired = true; +// boolean formatRequired = true; if (args.length < 4) args = Arrays.copyOf(args, 4); @@ -460,11 +460,11 @@ public S LoadFrom(Reader reader, Object... args) throws IOExce if (args[3] == null) args[3] = getProtocols(); - StringBuilder str = readAndFormat(reader, formatRequired); - List objs = splitAndParse(str, args); - addAll(objs); +// StringBuilder str = readAndFormat(reader, formatRequired); +// List objs = splitAndParse(str, args); +// addAll(objs); -// readAndParse(values(), reader, 512, args); + readAndParse(values(), reader, 512, args); if (parent == null) getImports().removeImportsOf(this); @@ -472,10 +472,12 @@ public S LoadFrom(Reader reader, Object... args) throws IOExce } /** + * This acts basically as a lexer for Juss and Json... + * * @param result | Resulting collection of objects to fill up with parsed objects from reader. * @param reader | The reader to {@link Reader#read(char[], int, int)}. * @param charBuffLen | Length of internal char buffer (number of chars that are processed at once). Recommended length is 512, in case of increase should be the power of 2. - * @param parserArgs | Additional arguments to use. Take a look at {@link Serializer#LoadFrom(File, Object...)}. + * @param parserArgs | Additional arguments to use. Take a look at {@link Serializer#loadFrom(File, Object...)}. * * @throws IOException If {@link Reader} instance throws it during reading... * @@ -910,7 +912,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence, Object...)} + {@link Serializer#loadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -918,15 +920,15 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File, Object...)} + {@link Serializer#loadFrom(File, Object...)} {@link Reader} - {@link Serializer#LoadFrom(Reader)} + {@link Serializer#loadFrom(Reader)} {@link InputStream} - {@link Serializer#LoadFrom(InputStream, Object...)} + {@link Serializer#loadFrom(InputStream, Object...)} {@link URL} @@ -977,7 +979,7 @@ Obtained serializer content (return) {@link CharSequence} - {@link Serializer#LoadFrom(CharSequence, Object...)} + {@link Serializer#loadFrom(CharSequence, Object...)} {@link CharSequence} (as http address) @@ -985,15 +987,15 @@ Obtained serializer content (return) {@link File} - {@link Serializer#LoadFrom(File, Object...)} + {@link Serializer#loadFrom(File, Object...)} {@link Reader} - {@link Serializer#LoadFrom(Reader)} + {@link Serializer#loadFrom(Reader)} {@link InputStream} - {@link Serializer#LoadFrom(InputStream, Object...)} + {@link Serializer#loadFrom(InputStream, Object...)} {@link URL} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 8296c0f..89f1f5c 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -124,7 +124,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile return scope; try { - return scope.LoadFrom(new StringReader(str), compilerArgs); + return scope.loadFrom(new StringReader(str), compilerArgs); } catch (IOException e) { @@ -191,7 +191,7 @@ else if (args.length > 0 && args[0] instanceof Serializer) GenericScope parent; if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) sb.append(ImportsProvider.getAliasFor(serializer, getClass()) + " "); - return serializer.SerializeAsSubscope(sb, args); + return serializer.serializeAsSubscope(sb, args); } catch (IOException e) { From b5c67ca5402d8eb112af1b8855f15a3efc47854d Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 11 Jul 2025 01:22:24 +0200 Subject: [PATCH 53/75] array converter supp for 0 len and 1 len arrs --- .../juss/converters/ArrayConverter.java | 54 ++++++++++--------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 584d913..ac129b8 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -49,18 +49,19 @@ public class ArrayConverter implements DataConverter @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { - if (indexOfNotInObj(str, ' ') > 0) + int len, startI = 0; + if ((len = str.length()) != 0 && str.charAt(0) == '@' || (startI = indexOfNotInObj(str, 1, len, 0, true, ' ')) > 0) { - String[] strObjs = tokenize(str); - int len, i = 0; - Object[] objs = new Object[len = strObjs.length]; + String[] strObjs = tokenize(startI == 0 ? str.substring(1).trim() : str, startI); + int arrLen, i = 0; + Object[] arr = new Object[arrLen = strObjs.length]; if (args.length < 2 || !(args[1] instanceof Boolean) || (boolean) args[1]) { Class arrClass = null; - for (; i < len; i++) + for (; i < arrLen; i++) { - Object obj = objs[i] = myHomeRegistry.parse(strObjs[i], args); + Object obj = arr[i] = myHomeRegistry.parse(strObjs[i], args); if (obj != null) if (arrClass == null) arrClass = obj.getClass(); @@ -71,16 +72,16 @@ else if (arrClass != obj.getClass()) if (arrClass != null && arrClass != Object.class) try { - return castArray(objs, arrClass); + return castArray(arr, arrClass); } catch (IllegalArgumentException e) {} - return objs; + return arr; } - for (; i < len; i++) - objs[i] = myHomeRegistry.parse(strObjs[i], args); - return objs; + for (; i < arrLen; i++) + arr[i] = myHomeRegistry.parse(strObjs[i], args); + return arr; } return CONTINUE; } @@ -108,21 +109,23 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. Object[] elms = fromAmbiguousArray(obj); final int len = elms.length; - StringBuilder sb = new StringBuilder(); + if (len == 0) + return "@"; + + StringBuilder sb = new StringBuilder("@"); if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) // Format { for (int i = 0, sizeEndl = 10000; i < len; i++) { - if (i != 0) - if (sb.length() > sizeEndl) - { - sb.append('\n'); - for (int j = 0; j < tabs+1; j++) - sb.append('\t'); - sizeEndl += 10000; - } - else - sb.append(' '); + if (sb.length() > sizeEndl) + { + sb.append('\n'); + for (int j = 0; j < tabs+1; j++) + sb.append('\t'); + sizeEndl += 10000; + } + else + sb.append(' '); CharSequence str = myHomeRegistry.toString(elms[i], args); char ch = str.charAt(0); @@ -136,8 +139,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. { for (int i = 0; i < len; i++) { - if (i != 0) - sb.append(' '); + sb.append(' '); CharSequence str = myHomeRegistry.toString(elms[i], args); char ch = str.charAt(0); @@ -167,8 +169,8 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDe * * @since 1.3.2 */ - public String[] tokenize(String str) + public String[] tokenize(String str, int firstSplitterI) { - return splitValues(str, ' '); + return str.isEmpty() ? new String[0] : splitValues(str, firstSplitterI, 0, 2, new char[0], ' '); } } \ No newline at end of file From e788859d599eee76aadb5099e386b0afeae4f7aa Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 11 Jul 2025 13:37:35 +0200 Subject: [PATCH 54/75] hashCode for GenericScope --- .../java/org/ugp/serialx/GenericScope.java | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index d7b0a30..e9b1cde 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -23,7 +23,7 @@ /** - * This collection is some sort of hybrid between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
+ * This collection is some sort of hybrid, or more accurately "union" between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
* Note: Variables are managed and accessed classically via {@link Map} methods such as put(KeyT key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
* Also this is java representation of JUSS GenericScope group such as: *
@@ -117,10 +117,19 @@ public boolean equals(Object obj)
 	public String toString()
 	{
 		String name = getClass().getSimpleName();
-		if (variablesCount() > 0 ^ valuesCount() > 0)
-			return name + (variablesCount() > 0 ? variables() : values());
-		else
-			return name + toUnifiedList();
+		final int varCount;
+		if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0)
+			return name + (varCount > 0 ? variables() : values());
+		return name + toUnifiedList();
+	}
+	
+	@Override
+	public int hashCode() 
+	{
+		final int varCount;
+		if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0)
+			return (varCount > 0 ? variables() : values()).hashCode();
+		return Objects.hash(variables(), values());
 	}
 	
 	@SuppressWarnings("unchecked")

From 6f506c5d27d00a2b02034ebee9f3130578be56b1 Mon Sep 17 00:00:00 2001
From: Programmer001 
Date: Fri, 11 Jul 2025 19:54:46 +0200
Subject: [PATCH 55/75] mvn 1.3.9

---
 SerialX-core/pom.xml      | 2 +-
 SerialX-json/pom.xml      | 4 ++--
 SerialX-juss/pom.xml      | 4 ++--
 SerialX-operators/pom.xml | 4 ++--
 pom.xml                   | 2 +-
 5 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml
index ea51a11..e92f136 100644
--- a/SerialX-core/pom.xml
+++ b/SerialX-core/pom.xml
@@ -10,7 +10,7 @@
 
 	org.ugp.serialx
 	serialx-core
-	1.3.9-SNAPSHOT
+	1.3.9
 
 	SerialX core
 	Core of SerialX. Contains core features and utilities shared across the library.
diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml
index 9be6c46..3705816 100644
--- a/SerialX-json/pom.xml
+++ b/SerialX-json/pom.xml
@@ -10,7 +10,7 @@
 
 	org.ugp.serialx
 	serialx-json
-	1.3.9-SNAPSHOT
+	1.3.9
 
 	SerialX json
 	SerialX Json support
@@ -19,7 +19,7 @@
 		
 			org.ugp.serialx
 			serialx-juss
-			1.3.9-SNAPSHOT
+			1.3.9
 		
 	
 
\ No newline at end of file
diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml
index 22e3218..a1088c7 100644
--- a/SerialX-juss/pom.xml
+++ b/SerialX-juss/pom.xml
@@ -10,7 +10,7 @@
 
 	org.ugp.serialx
 	serialx-juss
-	1.3.9-SNAPSHOT
+	1.3.9
 
 	SerialX juss
 	SerialX support for Java Universal Serial Script data format, custom default format of SerialX!
@@ -19,7 +19,7 @@
 		
 			org.ugp.serialx
 			serialx-core
-			1.3.9-SNAPSHOT
+			1.3.9
 		
 	
 
\ No newline at end of file
diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml
index c7f9b69..6a09189 100644
--- a/SerialX-operators/pom.xml
+++ b/SerialX-operators/pom.xml
@@ -10,7 +10,7 @@
 
 	org.ugp.serialx
 	serialx-operators
-	1.3.9-SNAPSHOT
+	1.3.9
 
 	SerialX operators
 	This modul contains basic operators contained in almost every programing language...
@@ -19,7 +19,7 @@
 		
 			org.ugp.serialx
 			serialx-core
-			1.3.9-SNAPSHOT
+			1.3.9
 		
 	
 
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 3b019da..47659e7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -57,7 +57,7 @@
 
 	
 		8
-		1.3.9-SNAPSHOT 
+		1.3.9 
 
 		UTF-8
 		${java.version}

From 5385b4ed6ffeb8e00bc5716493feb17c55b7f417 Mon Sep 17 00:00:00 2001
From: Programmer001 
Date: Thu, 24 Jul 2025 22:26:37 +0200
Subject: [PATCH 56/75] Java doc fixes

---
 .../src/main/java/org/ugp/serialx/Registry.java    | 11 ++++-------
 .../src/main/java/org/ugp/serialx/Scope.java       | 14 +++++++-------
 .../src/main/java/org/ugp/serialx/Serializer.java  |  8 ++++----
 .../src/main/java/org/ugp/serialx/Utils.java       | 10 +++++++---
 .../org/ugp/serialx/converters/DataConverter.java  |  2 ++
 .../ugp/serialx/converters/ProtocolConverter.java  |  5 +++--
 .../converters/SerializableBase64Converter.java    |  2 +-
 .../ugp/serialx/converters/StringConverter.java    |  2 +-
 .../serialx/protocols/SerializationProtocol.java   |  2 ++
 .../java/org/ugp/serialx/json/JsonSerializer.java  |  2 +-
 .../java/org/ugp/serialx/juss/JussSerializer.java  |  7 ++++---
 .../serialx/juss/converters/ArrayConverter.java    |  1 +
 .../juss/protocols/SelfSerializableProtocol.java   |  2 ++
 pom.xml                                            |  7 +++++++
 14 files changed, 46 insertions(+), 29 deletions(-)

diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java
index 2531833..b0cde1b 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Registry.java
@@ -86,7 +86,7 @@ public void add(int index, E element)
 	{
 		E contained = get((Class) element.getClass());
 		if (contained != null)
-			remove(contained);		
+			remove(contained);
 		super.add(index, element);
 	}
 	
@@ -128,8 +128,6 @@ protected void addDuplicatively(int index, E element)
 	/**
 	 * @param elms | Array o elements to add!
 	 * 
-	 * @return {@link Registry#addAll(int, Object...)}
-	 * 
 	 * @since 1.3.0
 	 */
 	public void addAll(@SuppressWarnings("unchecked") E... elms)
@@ -138,10 +136,9 @@ public void addAll(@SuppressWarnings("unchecked") E... elms)
 	}
 	
 	/**
+	 * @param index | Index at which the specified elements should be inserted
 	 * @param elms | Array o elements to add!
 	 * 
-	 * @return {@link Registry#addAll(int, Collection)}
-	 * 
 	 * @since 1.3.0
 	 */
 	public void addAll(int index, @SuppressWarnings("unchecked") E... elms)
@@ -219,9 +216,9 @@ public int addBefore(Class cls, boolean includeChildrens, E element
 	 * 
 	 * @since 1.3.0
 	 */
-	public void addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element)
+	public int addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element)
 	{
-		addAllBefore(cls, false, element);
+		return addAllBefore(cls, false, element);
 	}
 	
 	/**
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
index ff1108c..69b6b0d 100644
--- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
+++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java
@@ -615,7 +615,7 @@ public Scope getScope(int scopeValueIndex)
 	}
 	
 	/**
-	 * @param scopesOrderIndex | Order index of sub-scope.
+	 * @param subscopesOrderIndex | Order index of sub-scope.
 	 * 
 	 * @return Sub-scope with required number. Similar to {@link Scope#getScope(int)} however this will ignore non scope values.
 	 * 

@@ -732,9 +732,9 @@ public T toObjectOf(int scopesValueIndex, Class objClass) throws Exceptio * * @since 1.2.5 */ - public T toObjectOf(String variableWithscope, Class objClass) throws Exception + public T toObjectOf(String variableWithScope, Class objClass) throws Exception { - return toObjectOf(variableWithscope, objClass, null); + return toObjectOf(variableWithScope, objClass, null); } /** @@ -752,9 +752,9 @@ public T toObjectOf(String variableWithscope, Class objClass) throws Exce * * @since 1.2.5 */ - public T toObjectOf(String variableWithscope, Class objClass, T defaultValue) throws Exception + public T toObjectOf(String variableWithScope, Class objClass, T defaultValue) throws Exception { - return toObjectOf(variableWithscope, objClass, defaultValue, SerializationProtocol.REGISTRY); + return toObjectOf(variableWithScope, objClass, defaultValue, SerializationProtocol.REGISTRY); } /** @@ -774,9 +774,9 @@ public T toObjectOf(String variableWithscope, Class objClass, T defaultVa * @since 1.3.2 */ @SuppressWarnings("unchecked") - public T toObjectOf(String variableWithscope, Class objClass, T defaultValue, ProtocolRegistry protocolsToUse) throws Exception + public T toObjectOf(String variableWithScope, Class objClass, T defaultValue, ProtocolRegistry protocolsToUse) throws Exception { - T obj = get(variableWithscope, defaultValue); + T obj = get(variableWithScope, defaultValue); if (obj instanceof GenericScope) return ((GenericScope) obj).toObject(objClass, protocolsToUse); return obj; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 9ee2fb7..e50f1be 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -265,8 +265,6 @@ public String toString(boolean serialize) throws IOException * @param f | File to write in. This must be a text file. * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! * - * @return String with variables and objects serialized in specific format. - * * @throws IOException if file can't be opened or serialization fails! * * @since 1.1.5 @@ -281,8 +279,6 @@ public void serializeTo(File f, Object... args) throws IOException * @param f | File to write in. This must be a text file. * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! * - * @return String with variables and objects serialized in specific format. - * * @throws IOException if file can't be opened or serialization fails! * * @since 1.1.5 @@ -349,6 +345,8 @@ public OutputStream serializeTo(OutputStream outputStream, Object... args) throw * * @return Source {@link Appendable} with variables and objects serialized in specific format. * + * @throws IOException depends on the implementation (likely when the provided source throws). + * * @since 1.3.2 */ public abstract A serializeTo(A source, Object... args) throws IOException; @@ -456,9 +454,11 @@ public Serializer emptyClone(Scope parent) throws Exception } /** + * @param typeOfClone | Specific type of the clone (has to extend Serializer). * @param parent | Parent scope of new Serializer instance! * * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * @throws Exception * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java index 8797639..9f4922f 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Utils.java @@ -391,16 +391,17 @@ public static Class[] ToClasses(Object... objs) } /** + * @param unwrap | If the box types should be unwrapped to primitives... * @param objs | Array of objects. * * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class * * @since 1.3.5 */ - public static Class[] ToClasses(boolean unwrapp, Object... objs) + public static Class[] ToClasses(boolean unwrap, Object... objs) { Class[] classes = new Class[objs.length]; - if (unwrapp) + if (unwrap) { for (int i = 0; i < classes.length; i++) { @@ -771,6 +772,9 @@ public static boolean isOneOf(int ch, char... chars) } /** + * @param str | Char sequence to search. + * @param oneOf | Chars to search for! + * * @return {@link String#contains(CharSequence)} for char sequence! * * @since 1.3.0 @@ -785,7 +789,7 @@ public static boolean contains(CharSequence str, char... oneOf) return false; } - for (int i = 0, len = str.length(); i < len; i++) + for (int i = 0, len = str.length(); i < len; i++) if (isOneOf(str.charAt(i), oneOf)) return true; return false; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 71bc6e2..ee92af7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -53,6 +53,8 @@ public static CharSequence objToString(Object obj, Object... args) } /** + * @param objToDescribe | Object to gen. comment for... + * * @return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataParser.class.getName() * * @since 1.3.2 diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 0084f8e..73ac0c9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -346,13 +346,14 @@ else if (args[3] instanceof SerializationProtocol) /** * @param str | String to check protocol class for! + * @param args | Args provided by the caller. Should contain {@link ImportsProvider}-like object at index 0. * * @return Class of the protocol or null if inserted statement is not protocol expression! * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! * * @since 1.3.0 */ - public static Class getProtocolExprClass(String str, Object... compilerArgs) + public static Class getProtocolExprClass(String str, Object... args) { int i = 0, len = str.length(); for (char ch; i < len; i++) @@ -361,7 +362,7 @@ public static Class getProtocolExprClass(String str, Object... compilerArgs) try { - Class cls = ImportsProvider.forName(compilerArgs.length > 0 ? compilerArgs[0] : null, str.substring(0, i), false, ProtocolConverter.class.getClassLoader()); + Class cls = ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(0, i), false, ProtocolConverter.class.getClassLoader()); if (cls != null) return cls; for (char ch; i < len; i++) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index 4d8dce4..28c84eb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -108,7 +108,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Ob * * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) */ - public static Object UnserializeClassis(String objStr) throws Exception + public static Object UnserializeClassis(String objStr) throws IOException, ClassNotFoundException { return new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(objStr))).readObject(); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 98dd99a..d214963 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -150,7 +150,7 @@ public void setSerializeStringNormally(boolean serializeStringNormally) /** * @param obj | Object to stringify directly. * - * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString(Registry, Object, Object...))}, it will be returned without ${ and }! + * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString(Registry, Object, Object...)}, it will be returned without ${ and }! * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 7316d46..2babf3b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -76,6 +76,8 @@ public String toString() * * @return Array of objects to serialize created from given object. * + * @throws Exception depends on the implementation (most likely reflection related exceptions). + * * @since 1.0.0 */ public abstract Object[] serialize(T object) throws Exception; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index ab8cb09..4f79246 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -332,7 +332,7 @@ Obtained serializer content (return) * - * @throws When something went wrong during deserialization! + * @throws Exception When something went wrong during deserialization! * * @since 1.3.5 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 8ca7696..af46fd8 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -32,6 +32,7 @@ import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; +import org.ugp.serialx.Utils; import org.ugp.serialx.converters.BooleanConverter; import org.ugp.serialx.converters.CharacterConverter; import org.ugp.serialx.converters.DataConverter; @@ -802,7 +803,7 @@ protected Object parseObject(ParserRegistry registry, String str, Object... pars * * @return Clone of value stored by variable with inserted name or null if there is no such a one! *

- * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ @@ -817,7 +818,7 @@ public T cloneOf(String variableKey) * * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! *

- * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ @@ -835,7 +836,7 @@ public T cloneOf(String variableKey, T defaultValue) * * @return Clone of independent value with valueIndex! *

- * Note: Cloning is done by {@link Serializer#Clone(Object, Registry, Object[], Object...))}! + * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index ac129b8..6040791 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -164,6 +164,7 @@ public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDe /** * @param str | String to tokenize! + * @param firstSplitterI | Index of first expected splitter char (space). * * @return String splitted according to defined rules! * diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index 9247b8a..68d15c0 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -3,6 +3,8 @@ /** * SelfSerializableProtocol is universal protocol to serialize any {@link SelfSerializable} instance. The condition of use is implementation of {@link SelfSerializable} interface and public constructor that can be called with content returned by specific {@link SelfSerializable#serialize()}! * + * @param Type of SelfSerializable class that this protocol should be applicable for... + * * @author PETO * * @since 1.2.2 diff --git a/pom.xml b/pom.xml index 47659e7..cf0ebc3 100644 --- a/pom.xml +++ b/pom.xml @@ -54,6 +54,13 @@ https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX + + + + github + https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX + + 8 From 508f8e71448967a35719746f80fa99184770ce43 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 27 Jul 2025 21:53:18 +0200 Subject: [PATCH 57/75] Appandable for toString --- .../serialx/converters/BooleanConverter.java | 10 ++++- .../converters/CharacterConverter.java | 6 ++- .../ugp/serialx/converters/DataConverter.java | 30 ++++++++++++- .../ugp/serialx/converters/DataParser.java | 35 +++++++++++++-- .../ugp/serialx/converters/NullConverter.java | 6 ++- .../serialx/converters/NumberConverter.java | 19 ++++---- .../serialx/converters/ProtocolConverter.java | 35 ++++++++------- .../SerializableBase64Converter.java | 10 ++--- .../serialx/converters/StringConverter.java | 15 ++++--- SerialX-devtools/pom.xml | 2 +- .../serialx/devtools/DebugParserRegistry.java | 12 ++--- .../devtools/SerializationDebugger.java | 22 +++++++--- .../org/ugp/serialx/json/JsonSerializer.java | 15 +++---- .../converters/JsonCharacterConverter.java | 6 ++- .../json/converters/JsonNumberConverter.java | 6 ++- .../json/converters/JsonObjectConverter.java | 29 ++++++------ .../converters/JsonVariableConverter.java | 20 +++++++-- .../org/ugp/serialx/juss/JussSerializer.java | 2 +- .../juss/converters/ArrayConverter.java | 44 ++++++++++--------- .../juss/converters/ImportConverter.java | 6 ++- .../juss/converters/ObjectConverter.java | 18 ++++---- .../juss/converters/VariableConverter.java | 41 ++++++----------- 22 files changed, 240 insertions(+), 149 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index c9ec4ba..a60c9c3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -3,6 +3,8 @@ import static java.lang.Boolean.*; import static org.ugp.serialx.Utils.equalsLowerCase; +import java.io.IOException; + /** * This converter is capable of converting {@link String}. * Its case insensitive! @@ -76,10 +78,14 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Boolean) - return isShorten() ? (boolean) obj ? "T" : "F" : (boolean) obj ? "true" : "false"; + { + if (isShorten()) + return source.append((boolean) obj ? 'T' : 'F'); + return source.append((boolean) obj ? "true" : "false"); + } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java index 624a560..35bfcfb 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.converters; +import java.io.IOException; + /** * This converter is capable of converting {@link Character}. * Its case sensitive! @@ -52,10 +54,10 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Character) - return "'"+(int) (char) obj+"'"; + return source.append("'"+(int) (char) obj+"'"); return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index ee92af7..0bd52c9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.converters; +import java.io.IOException; + /** * This is DataParser with extended functionality! {@link DataConverter} can also parse data like DataParser but is also capable of converting them back to string! * This to string convertation is performed by {@link DataConverter#toString(Object)} and result of this convertation supposed to be parsable by {@link DataConverter#parse(String, Object...)} meaning one converter supposed to be parsing and converting via the same string format! @@ -22,7 +24,33 @@ public interface DataConverter extends DataParser * * @since 1.3.0 */ - CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args); + @Deprecated + default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + try + { + return (CharSequence) toString(new StringBuilder().append(0), myHomeRegistry, obj, args); + } + catch (IOException e) + { + throw new RuntimeException(e); // Rare... + } + } + + /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return The source appendable after stringified object (obj) was appropriately appended into it. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @throws IOException When appending into source throws it... + * + * @since 1.3.9 + */ + Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException; /** * @param myHomeRegistry | Registry of parsers (might be null)! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index d9d1509..aa0fa34 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -1,5 +1,6 @@ package org.ugp.serialx.converters; +import java.io.IOException; import java.util.Collection; import org.ugp.serialx.LogProvider; @@ -29,10 +30,11 @@ public interface DataParser /** * This is connected with {@link DataParser#parse(String, Object...)} and {@link DataParser#parseObj(String, Object...)}! And its a way to tell that this parser is not suitable for parsing obtained string and search for optimal one should continue. + * Should not be modified under any circumstances, always treat as immutable! * * @since 1.3.0 */ - public static final String CONTINUE = new String(); + public static final Appendable CONTINUE = new StringBuilder(); /** * This is DataParser registry. Here your parser implementations should be registered in order to work properly! @@ -165,18 +167,43 @@ public DataConverter getConverterFor(Object obj, Object... args) * * @since 1.3.5 */ + @Deprecated public CharSequence toString(Object obj, Object... args) { - CharSequence str; + try + { + return (CharSequence) toString(new StringBuilder(), obj, args); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return The source appendable after stringified object (obj) was appropriately appended into it. + * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @throws IOException When appending into source throws it... + * + * @since 1.3.9 + */ + public Appendable toString(Appendable source, Object obj, Object... args) throws IOException + { + Appendable str; if (convertingCache != null) for (DataParser parser : convertingCache) - if (parser != null && (str = ((DataConverter) parser).toString(this, obj, args)) != CONTINUE) + if (parser != null && (str = ((DataConverter) parser).toString(source, this, obj, args)) != CONTINUE) return str; for (int i = 0, size = size(); i < size; i++) { DataParser parser = get(i); - if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(this, obj, args)) != CONTINUE) + if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, this, obj, args)) != CONTINUE) { if (convertingCache != null && i < convertingCache.length) convertingCache[i] = parser; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index 6cc784e..ffb381e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -2,6 +2,8 @@ import static org.ugp.serialx.Utils.equalsLowerCase; +import java.io.IOException; + /** * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. * Its case insensitive! @@ -49,10 +51,10 @@ public Object parse(ParserRegistry registry, String str, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj == null) - return "null"; + return source.append("null"); return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 5378cc8..31588dd 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -2,6 +2,8 @@ import static org.ugp.serialx.Utils.contains; +import java.io.IOException; + /** * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! * Its case insensitive! @@ -106,22 +108,23 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Number) { - StringBuilder str = new StringBuilder(format((Number) obj)); + String str; + source.append(str = format((Number) obj)); if (obj instanceof Double && !contains(str, '.')) - str.append('D'); + source.append('D'); else if (obj instanceof Float) - str.append('F'); + source.append('F'); else if (obj instanceof Long) - str.append('L'); + source.append('L'); else if (obj instanceof Short) - str.append('S'); + source.append('S'); else if (obj instanceof Byte) - str.append('Y'); - return str; + source.append('Y'); + return source; } return CONTINUE; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 73ac0c9..4b99623 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -4,6 +4,7 @@ import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.splitValues; +import java.io.IOException; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; @@ -166,24 +167,25 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { - return toString(myHomeRegistry, obj, null, args); + return toString(source, myHomeRegistry, obj, null, args); } /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param obj | Object to convert into string! * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * - * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * @return The source appendable after stringified object (obj) was appropriately appended into it. * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @since 1.3.5 */ @SuppressWarnings("unchecked") - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { if (obj == null) return CONTINUE; @@ -205,42 +207,45 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Serializ { Object[] objArgs = preferedProtocol.serialize(obj); final int len = objArgs.length; + + boolean wrap; + if (wrap = index > 0 && len != 0) + source.append('{'); - StringBuilder sb = new StringBuilder(ImportsProvider.getAliasFor(args[0], obj.getClass())); + source.append(ImportsProvider.getAliasFor(args[0], obj.getClass())); args = args.clone(); if (args[5] instanceof Byte && (byte) args[5] != 0) // Format { - for (int i = 0, sizeEndl = 10000; i < len; i++) + for (int i = 0; i < len; i++) { - if (sb.length() > sizeEndl) + if (i != 0 && i % 1000 == 0) { - sb.append('\n'); + source.append('\n'); for (int j = 0; j < tabs+1; j++) - sb.append('\t'); - sizeEndl += 10000; + source.append('\t'); } else - sb.append(' '); + source.append(' '); if (args.length > 2) args[2] = index + 1; // DO NOT TOUCH - sb.append(myHomeRegistry.toString(objArgs[i], args)); + myHomeRegistry.toString(source, objArgs[i], args); } } else { for (int i = 0; i < len; i++) { - sb.append(' '); + source.append(' '); if (args.length > 2) args[2] = index + 1; // DO NOT TOUCH - sb.append(myHomeRegistry.toString(objArgs[i], args)); + myHomeRegistry.toString(source, objArgs[i], args); } } args[4] = oldObjectClass; - return index > 0 && len != 0 ? sb.insert(0, '{').append('}') : sb; + return wrap ? source.append('}') : source; } catch (Exception e) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index 28c84eb..14c1d61 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -65,7 +65,7 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) } catch (Exception e) { - LogProvider.instance.logErr("Looks like there appear some problems with unserializing some object, the instance of java.io.Serializable from string \"" + arg + "\"! This string is most likely corrupted! See error below:", e); + LogProvider.instance.logErr("Looks like there were some problems with unserializing some object, the instance of java.io.Serializable from string \"" + arg + "\"! This string is most likely corrupted! See error below:", e); e.printStackTrace(); return null; } @@ -74,16 +74,16 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) { - if (arg instanceof Serializable) + if (obj instanceof Serializable) try { - return "#" + URLEncoder.encode(SerializeClassic((Serializable) arg), "UTF-8").replace('%', '#'); + return source.append('#').append(URLEncoder.encode(SerializeClassic((Serializable) obj), "UTF-8").replace('%', '#')); } catch (Exception e) { - LogProvider.instance.logErr("Looks like there appear some problems with serializing \"" + arg + "\", the instance of java.io.Serializable. This could happen when certain object contains non-transient unserializable objects. Use custom valid protocol for serializing \"" + arg + "\" might solve the problem!", e); + LogProvider.instance.logErr("Looks like there were some problems with serializing \"" + obj + "\", the instance of java.io.Serializable. This could happen when certain object contains non-transient unserializable objects. Using custom valid protocol for serializing \"" + obj + "\" might solve the problem!", e); e.printStackTrace(); return null; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index d214963..6d16bc3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -3,6 +3,7 @@ import static org.ugp.serialx.Utils.contains; import static org.ugp.serialx.Utils.indexOfNotInObj; +import java.io.IOException; import java.util.Map; import org.ugp.serialx.Registry; @@ -48,7 +49,7 @@ public class StringConverter implements DataConverter protected Map parsingCache; @Override - public String parse(ParserRegistry myHomeRegistry, String str, Object... args) + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { String result; int len; @@ -67,24 +68,24 @@ public String parse(ParserRegistry myHomeRegistry, String str, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { - if (arg instanceof String) + if (obj instanceof String) { - String str = arg.toString(); + String str = (String) obj; if (str.startsWith("${") && str.endsWith("}")) { str = str.substring(2, str.length()-1); if (str.contains("::") && indexOfNotInObj(str, ' ') > -1) - str = "{"+str+"}"; - return str; + return source.append('{').append(str).append('}'); + return source.append(str); } if (serializeStringNormally) { if (contains(str, '\"', '\n', '\r')) return CONTINUE; - return "\""+str+"\""; + return source.append('"').append(str).append('"'); } } return CONTINUE; diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 7ed2029..872b6ba 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - 1.3.8 + 1.3.9 \ No newline at end of file diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index cf31e39..10bfb25 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -1,5 +1,6 @@ package org.ugp.serialx.devtools; +import java.io.IOException; import java.util.Map; import java.util.TreeMap; @@ -49,7 +50,8 @@ public DebugParserRegistry clone(boolean copyStackTrace) } @Override - public CharSequence toString(Object obj, Object... args) { + public Appendable toString(Appendable source, Object obj, Object... args) throws IOException + { int iterationIndex = 0; if (args.length > 99 && args[99] instanceof Integer) { @@ -65,12 +67,12 @@ public CharSequence toString(Object obj, Object... args) { if (parser != null) { double t0 = System.nanoTime(); - str = ((DataConverter) parser).toString(this, obj, args); + str = (CharSequence) ((DataConverter) parser).toString(new StringBuilder(), this, obj, args); double t = System.nanoTime(); if (str != SerializationDebugger.CONTINUE) { iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return str; + return source.append(str); } } } @@ -81,14 +83,14 @@ public CharSequence toString(Object obj, Object... args) { if (parser instanceof DataConverter) { double t0 = System.nanoTime(); - str = ((DataConverter) parser).toString(this, obj, args); + str = (CharSequence) ((DataConverter) parser).toString(new StringBuilder(), this, obj, args); double t = System.nanoTime(); if(str != SerializationDebugger.CONTINUE) { if (convertingCache != null && i < convertingCache.length) convertingCache[i] = parser; iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return str; + return source.append(str); } } } diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index 1c36d7b..8f80171 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -2,6 +2,7 @@ import static org.ugp.serialx.Utils.multilpy; +import java.io.IOException; import java.io.PrintWriter; import java.util.Arrays; import java.util.List; @@ -40,15 +41,26 @@ public class SerializationDebugger implements DataConverter public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) { if (str.toLowerCase().startsWith(DEBUG_MARK)) - return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); + try + { + return printDebugs(null, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } return CONTINUE; } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof DebugWrapper) - return printDebugs(myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), ((DebugWrapper) obj).obj, null, args).toString(); + { + printDebugs(source, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), ((DebugWrapper) obj).obj, null, args); + return source; + } return CONTINUE; } @@ -59,7 +71,7 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. * * @since 1.3.5 */ - public Object printDebugs(DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) + public Object printDebugs(Appendable source, DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) throws IOException { if (out == null) out = new PrintWriter(System.err); @@ -127,7 +139,7 @@ else if (args[99] instanceof Integer && (int) args[99] > 0) out.println("\n"); out.flush(); - return strToParse; + return source.append(strToParse); } printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", ""); diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 4f79246..5744e59 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -200,28 +200,23 @@ public ParserRegistry getParsers() * @since 1.3.2 */ @Override - protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException + protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object... args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); - source.append(serializedVar); + parsersToUse.toString(source, varToSerialize, args); if (isLast) return source; return source.append(','); } - /** - * This should append serializedVal into source based on arguments, add separator and return source! - * - * @since 1.3.2 - */ @Override - protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException + protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object... args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); - source.append(serializedVal); - if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) + parsersToUse.toString(source, objToSerialize, args); + if (isLast /*|| serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1*/) return source; return source.append(','); } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java index 9067423..dc23217 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.json.converters; +import java.io.IOException; + import org.ugp.serialx.converters.CharacterConverter; /** @@ -24,10 +26,10 @@ public JsonCharacterConverter(boolean formatAsString) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Character) - return isFormatAsString() ? "\""+obj+"\"" : String.valueOf((int) (char) obj); + return source.append(isFormatAsString() ? "\""+obj+"\"" : String.valueOf((int) (char) obj)); return CONTINUE; } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java index 402f0e8..666667f 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.json.converters; +import java.io.IOException; + import org.ugp.serialx.converters.NumberConverter; /** @@ -12,10 +14,10 @@ public class JsonNumberConverter extends NumberConverter { @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Number) - return format((Number) obj); + return source.append(format((Number) obj)); return CONTINUE; } } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index 585b4e6..c66bb21 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -1,5 +1,6 @@ package org.ugp.serialx.json.converters; +import java.io.IOException; import java.util.Map; import org.ugp.serialx.Scope; @@ -20,36 +21,36 @@ public class JsonObjectConverter extends ObjectConverter { @SuppressWarnings("unchecked") @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object arg, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { - if (arg == null) + if (obj == null) return CONTINUE; - if (arg.getClass().isArray()) - return super.toString(myHomeRegistry, new Scope(Utils.fromAmbiguousArray(arg)), args); + if (obj.getClass().isArray()) + return super.toString(source, myHomeRegistry, new Scope(Utils.fromAmbiguousArray(obj)), args); - if (arg instanceof Map) + if (obj instanceof Map) { - Map map = (Map) arg; + Map map = (Map) obj; if (map.isEmpty()) - return "{}"; + return source.append("{}"); if (map.keySet().iterator().next() instanceof CharSequence) - return super.toString(myHomeRegistry, new Scope((Map) map), args); + return super.toString(source, myHomeRegistry, new Scope((Map) map), args); } - SerializationProtocol prot = (SerializationProtocol) getProtocolFor(arg, SerializationProtocol.MODE_SERIALIZE, args); - if (prot != null && !(arg instanceof Scope)) + SerializationProtocol prot = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE, args); + if (prot != null && !(obj instanceof Scope)) try { - Object[] objArgs = prot.serialize(arg); + Object[] objArgs = prot.serialize(obj); if (objArgs.length == 1 && objArgs[0] instanceof Scope) - return super.toString(myHomeRegistry, objArgs[0], args); - return super.toString(myHomeRegistry, new Scope(objArgs), args); + return super.toString(source, myHomeRegistry, objArgs[0], args); + return super.toString(source, myHomeRegistry, new Scope(objArgs), args); } catch (Exception e) {} - return super.toString(myHomeRegistry, arg, prot, args); + return super.toString(source, myHomeRegistry, obj, prot, args); } @Override diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java index 5d45896..a41ba05 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java @@ -1,5 +1,8 @@ package org.ugp.serialx.json.converters; +import java.io.IOException; +import java.util.Map.Entry; + import org.ugp.serialx.juss.converters.VariableConverter; /** @@ -10,10 +13,19 @@ public class JsonVariableConverter extends VariableConverter { @Override - protected StringBuilder appendEntry(StringBuilder keyString, CharSequence valueString, Object value, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { - if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) - return keyString.insert(0, '"').append("\" : ").append(valueString); - return keyString.insert(0, '"').append("\":").append(valueString); + if (obj instanceof Entry) + { + Entry var = (Entry) obj; + + source.append('"').append(String.valueOf(var.getKey())); + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + source.append("\" : "); + else + source.append("\":"); + return myHomeRegistry.toString(source, var.getValue(), args); + } + return CONTINUE; } } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index af46fd8..d9f7512 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,7 +1,7 @@ package org.ugp.serialx.juss; import static org.ugp.serialx.Utils.Clone; -import static org.ugp.serialx.Utils.*; +import static org.ugp.serialx.Utils.ENDL; import static org.ugp.serialx.Utils.InvokeStaticFunc; import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.isOneOf; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 6040791..003a296 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -5,6 +5,8 @@ import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.splitValues; +import java.io.IOException; + import org.ugp.serialx.converters.DataConverter; /** @@ -87,7 +89,7 @@ else if (arrClass != obj.getClass()) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj != null && myHomeRegistry != null && obj.getClass().isArray()) { @@ -110,47 +112,49 @@ public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object.. Object[] elms = fromAmbiguousArray(obj); final int len = elms.length; if (len == 0) - return "@"; - - StringBuilder sb = new StringBuilder("@"); + return source.append('@'); + source.append(index > 0 ? "(@" : "@"); + + StringBuilder elmStr = new StringBuilder(); if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) // Format { - for (int i = 0, sizeEndl = 10000; i < len; i++) + for (int i = 0; i < len; i++) { - if (sb.length() > sizeEndl) + if (i != 0 && i % 1000 == 0) { - sb.append('\n'); + source.append('\n'); for (int j = 0; j < tabs+1; j++) - sb.append('\t'); - sizeEndl += 10000; + source.append('\t'); } else - sb.append(' '); + source.append(' '); - CharSequence str = myHomeRegistry.toString(elms[i], args); - char ch = str.charAt(0); + elmStr.setLength(0); + myHomeRegistry.toString(elmStr, elms[i], args); + char ch = elmStr.charAt(0); if ((ch | ' ') == '{') - sb.append('(').append(str).append(')'); + source.append('(').append(elmStr).append(')'); else - sb.append(str); + source.append(elmStr); } } else { for (int i = 0; i < len; i++) { - sb.append(' '); + source.append(' '); - CharSequence str = myHomeRegistry.toString(elms[i], args); - char ch = str.charAt(0); + elmStr.setLength(0); + myHomeRegistry.toString(elmStr, elms[i], args); + char ch = elmStr.charAt(0); if ((ch | ' ') == '{') - sb.append('(').append(str).append(')'); + source.append('(').append(elmStr).append(')'); else - sb.append(str); + source.append(elmStr); } } - return index > 0 ? sb.insert(0, '(').append(')') : sb; + return index > 0 ? source.append(')') : source; } } return CONTINUE; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java index 9812b9d..0104af6 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java @@ -1,5 +1,7 @@ package org.ugp.serialx.juss.converters; +import java.io.IOException; + import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; @@ -62,11 +64,11 @@ else if ((index = (str = str.trim()).indexOf("=>")) > -1) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) { - return obj.toString(); + return source.append(obj.toString()); } return CONTINUE; } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 89f1f5c..06e3299 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -15,6 +15,7 @@ import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.ProtocolConverter; import org.ugp.serialx.converters.SerializableBase64Converter; +import org.ugp.serialx.converters.DataParser.ParserRegistry; import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.juss.JussSerializer; import org.ugp.serialx.protocols.SerializationProtocol; @@ -136,25 +137,25 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { - return toString(myHomeRegistry, obj, null, args); + return toString(source, myHomeRegistry, obj, null, args); } /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param obj | Object to convert into string! * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * - * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + * @return The source appendable after stringified object (obj) was appropriately appended into it. * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @since 1.3.5 */ @SuppressWarnings("unchecked") - @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { if (obj instanceof Scope) { @@ -187,11 +188,10 @@ else if (args.length > 0 && args[0] instanceof Serializer) try { - StringBuilder sb = new StringBuilder(); GenericScope parent; if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) - sb.append(ImportsProvider.getAliasFor(serializer, getClass()) + " "); - return serializer.serializeAsSubscope(sb, args); + source.append(ImportsProvider.getAliasFor(serializer, getClass())).append(' '); + return serializer.serializeAsSubscope(source, args); } catch (IOException e) { @@ -199,7 +199,7 @@ else if (args.length > 0 && args[0] instanceof Serializer) } } - return super.toString(myHomeRegistry, obj, preferedProtocol, args); + return super.toString(source, myHomeRegistry, obj, preferedProtocol, args); } @Override diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index ecc5051..e060202 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -3,6 +3,7 @@ import static org.ugp.serialx.Utils.contains; import static org.ugp.serialx.Utils.splitValues; +import java.io.IOException; import java.util.AbstractMap; import java.util.Map; import java.util.Map.Entry; @@ -10,7 +11,6 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.VariableParser; /** @@ -132,42 +132,27 @@ public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) } @Override - public CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { if (obj instanceof Entry) { Entry var = (Entry) obj; final Object key, val = var.getValue(); - return appendEntry(new StringBuilder((key = var.getKey()) instanceof String ? - (String) key : - myHomeRegistry.toString(key, args) - ), myHomeRegistry.toString(val, args), val, args); + if ((key = var.getKey()) instanceof String) + source.append((String) key); + else // We are likely GenericScope + myHomeRegistry.toString(source, key, args); + + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + source.append(" = "); + else + source.append('='); + + return myHomeRegistry.toString(source, val, args); } return CONTINUE; } - - /** - * @param keyString | The string builder containing the key as string. - * @param valueString | The string containing the serialized value. - * @param value | The real value, the valueString before it was serialized... - * @param args | Same as {@link DataParser#parse(org.ugp.serialx.converters.DataParser.ParserRegistry, String, Object...)} - * - * @return Should return the string form of an entry (key value pair). Preferably constructed by appending some form of assignment operator (such as =) to the keyString and then appending the valueString at the end with some formating around it if needed. - * No unrelated characters should be included! - * - * @since 1.3.9 - */ - protected StringBuilder appendEntry(StringBuilder keyString, CharSequence valueString, Object value, Object... args) - { -// int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; -// return sb -// .append(val instanceof GenericScope && !((GenericScope) val).isEmpty() ? (jsonStyle ? " : " : " =\n" + multilpy('\t', tabs)) : (jsonStyle ? " : " : " = ")) -// .append(myHomeRegistry.toString(val, args)); - if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) - return keyString.append(" = ").append(valueString); - return keyString.append("=").append(valueString); - } @SuppressWarnings("unchecked") @Override From 7062a06eef5d2c6c7ef600a4a17ac4ecec46a334 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 28 Jul 2025 00:24:19 +0200 Subject: [PATCH 58/75] polishing --- .../ugp/serialx/converters/DataConverter.java | 2 +- .../org/ugp/serialx/json/JsonSerializer.java | 4 +- .../org/ugp/serialx/juss/JussSerializer.java | 51 +++++++++++-------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 0bd52c9..1360503 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -29,7 +29,7 @@ default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object. { try { - return (CharSequence) toString(new StringBuilder().append(0), myHomeRegistry, obj, args); + return (CharSequence) toString(new StringBuilder(), myHomeRegistry, obj, args); } catch (IOException e) { diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 5744e59..9667382 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -200,7 +200,7 @@ public ParserRegistry getParsers() * @since 1.3.2 */ @Override - protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object... args) throws IOException + protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); @@ -211,7 +211,7 @@ protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, E } @Override - protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object... args) throws IOException + protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index d9f7512..8a3b25a 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -253,10 +253,21 @@ public String Var(String name, T value, boolean isValue) */ public String StaticMember(Class cls, String staticMethodName, Object... args) { - StringBuilder sb = new StringBuilder(); - for (int i = 0, len = args.length; i < len; i++) - sb.append(getParsers().toString(args[i], this, 0, 0, getProtocols(), getFormat())).append(i < len-1 ? " " : ""); - return Code(cls.getName() + "::" + staticMethodName + (args.length <= 0 ? "" : " ") + sb); + StringBuilder sb = new StringBuilder(cls.getName()).append("::").append(staticMethodName); + for (int i = 0, len = args.length; i < len; i++) + { + sb.append(' '); + + try + { + getParsers().toString(sb, args[i], this, 0, 0, getProtocols(), getFormat()); + } + catch (IOException e) + { + throw new RuntimeException(e); // No... + } + } + return Code(sb); } /** @@ -316,7 +327,7 @@ else if (args[1] instanceof Integer) { for (Entry var : variables.entrySet()) //Vars { - appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); + appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); if (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty()) GenerateComment(source, reg, var); @@ -328,7 +339,7 @@ else if (format != 0) { for (Entry var : variables.entrySet()) //Vars { - appandVar(source, reg.toString(var, args), var, tabs, i >= varLen-1 && valuesLen <= 0); + appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); if (++i < varLen || valuesLen > 0) source.append('\n'); @@ -338,7 +349,7 @@ else if (format != 0) { for (Entry var : variables.entrySet()) //Vars { - appandVar(source, reg.toString(var, args), var, tabs, i++ >= varLen-1 && valuesLen <= 0); + appandVar(source, reg, var, tabs, i++ >= varLen-1 && valuesLen <= 0, args); } } } @@ -350,10 +361,8 @@ else if (format != 0) if (i != 0) source.append('\n'); - Object obj = objs.get(i); - CharSequence serialized = reg.toString(obj, args); - - appandVal(source, serialized, obj, tabs, i == valuesLen-1); + Object obj; + appandVal(source, reg, obj = objs.get(i), tabs, i == valuesLen-1, args); if (!(obj instanceof Scope) || ((Scope) obj).isEmpty()) GenerateComment(source, reg, obj); } @@ -365,16 +374,14 @@ else if (format != 0) if (i != 0) source.append('\n'); - Object obj; - appandVal(source, reg.toString(obj = objs.get(i), args), obj, tabs, i == valuesLen-1); + appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); } } else // No formating { for (i = 0; i < valuesLen; i++) //Values { - Object obj; - appandVal(source, reg.toString(obj = objs.get(i), args), obj, tabs, i == valuesLen-1); + appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); } } @@ -386,31 +393,31 @@ else if (format != 0) } /** - * This should append serializedVar into source based on arguments, add separator and return source! + * his should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) varToSerialize into source based on arguments, add separator and return source! * * @since 1.3.2 */ - protected Appendable appandVar(Appendable source, CharSequence serializedVar, Entry var, int tabs, boolean isLast) throws IOException + protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); - source.append(serializedVar); + source.append((CharSequence) parsersToUse.toString(new StringBuilder(), varToSerialize, args)); if (isLast) return source; return source.append(';'); } /** - * This should append serializedVal into source based on arguments, add separator and return source! + * This should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) objToSerialize into source based on arguments, add separator and return source! * * @since 1.3.2 */ - protected Appendable appandVal(Appendable source, CharSequence serializedVal, Object value, int tabs, boolean isLast) throws IOException + protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException { if (format != 0) source.append(multilpy('\t', tabs)); - source.append(serializedVal); - if (isLast || serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1) + source.append((CharSequence) parsersToUse.toString(new StringBuilder(), objToSerialize, args)); + if (isLast /*|| serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1*/) return source; return source.append(';'); } From 14d4e233c0cc1e4b95a56e83695dde0e00f685b2 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 28 Jul 2025 23:17:32 +0200 Subject: [PATCH 59/75] ... --- .../src/main/java/org/ugp/serialx/juss/JussSerializer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 8a3b25a..927de3a 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -401,7 +401,7 @@ protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, E { if (format != 0) source.append(multilpy('\t', tabs)); - source.append((CharSequence) parsersToUse.toString(new StringBuilder(), varToSerialize, args)); + parsersToUse.toString(source, varToSerialize, args); if (isLast) return source; return source.append(';'); @@ -416,7 +416,7 @@ protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, O { if (format != 0) source.append(multilpy('\t', tabs)); - source.append((CharSequence) parsersToUse.toString(new StringBuilder(), objToSerialize, args)); + parsersToUse.toString(source, objToSerialize, args); if (isLast /*|| serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1*/) return source; return source.append(';'); From e3ba1a9945683b03bc28c1d20b27fe2214ec1e54 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 1 Aug 2025 23:28:21 +0200 Subject: [PATCH 60/75] Micro optims and no ; after // --- .../ugp/serialx/converters/DataConverter.java | 2 +- .../ugp/serialx/converters/DataParser.java | 20 ++++++------- .../serialx/converters/ProtocolConverter.java | 2 +- .../serialx/converters/StringConverter.java | 6 ++++ .../serialx/devtools/DebugParserRegistry.java | 10 +++---- .../org/ugp/serialx/json/JsonSerializer.java | 6 ++-- .../org/ugp/serialx/juss/JussSerializer.java | 6 ++-- .../juss/converters/ObjectConverter.java | 29 ------------------- 8 files changed, 27 insertions(+), 54 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 1360503..28ab4c0 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -43,7 +43,7 @@ default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object. * @param obj | Object to convert into string! * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * - * @return The source appendable after stringified object (obj) was appropriately appended into it. + * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @throws IOException When appending into source throws it... diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index aa0fa34..cf99076 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -82,7 +82,7 @@ public static class ParserRegistry extends Registry implements DataP private static final long serialVersionUID = -2598324826689380752L; protected DataParser[] parsingCache; - protected DataParser[] convertingCache; + protected DataConverter[] convertingCache; /** * Constructs an {@link ParserRegistry} with the specified initial capacity. @@ -185,7 +185,7 @@ public CharSequence toString(Object obj, Object... args) * @param obj | Object to convert into string! * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! * - * @return The source appendable after stringified object (obj) was appropriately appended into it. + * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @throws IOException When appending into source throws it... @@ -196,8 +196,8 @@ public Appendable toString(Appendable source, Object obj, Object... args) throws { Appendable str; if (convertingCache != null) - for (DataParser parser : convertingCache) - if (parser != null && (str = ((DataConverter) parser).toString(source, this, obj, args)) != CONTINUE) + for (DataConverter parser : convertingCache) + if (parser != null && (str = parser.toString(source, this, obj, args)) != CONTINUE) return str; for (int i = 0, size = size(); i < size; i++) @@ -206,7 +206,7 @@ public Appendable toString(Appendable source, Object obj, Object... args) throws if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, this, obj, args)) != CONTINUE) { if (convertingCache != null && i < convertingCache.length) - convertingCache[i] = parser; + convertingCache[i] = (DataConverter) parser; return str; } } @@ -326,9 +326,9 @@ public int[] preCache(Class classOfParserToPrecache) ret[0] = i; } - if (i < convertingCache.length) + if (i < convertingCache.length && parser instanceof DataConverter) { - convertingCache[i] = parser; + convertingCache[i] = (DataConverter) parser; ret[1] = i; } @@ -346,7 +346,7 @@ public int[] preCache(Class classOfParserToPrecache) public void resetCache() { int size = size(); - resetCache(new DataParser[size], new DataParser[size]); + resetCache(new DataParser[size], new DataConverter[size]); } /** @@ -357,7 +357,7 @@ public void resetCache() * * @since 1.3.5 */ - public void resetCache(DataParser[] parsingCache, DataParser[] convertingCache) + public void resetCache(DataParser[] parsingCache, DataConverter[] convertingCache) { if (parsingCache != null) this.parsingCache = parsingCache; @@ -390,7 +390,7 @@ public DataParser[] getParsingCache() * * @since 1.3.5 */ - public DataParser[] getConverterCache() + public DataConverter[] getConverterCache() { return convertingCache; } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 4b99623..300c8b8 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -179,7 +179,7 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * - * @return The source appendable after stringified object (obj) was appropriately appended into it. + * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @since 1.3.5 diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 6d16bc3..1628c92 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -78,6 +78,12 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj str = str.substring(2, str.length()-1); if (str.contains("::") && indexOfNotInObj(str, ' ') > -1) return source.append('{').append(str).append('}'); + + if (indexOfNotInObj(str, "//") != -1) + { + source.append(str); + return null; // No append ; when ends with // + } return source.append(str); } diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index 10bfb25..fd390d5 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -63,15 +63,15 @@ public Appendable toString(Appendable source, Object obj, Object... args) throws if (convertingCache != null) for (int i = 0; i < convertingCache.length; i++) { - DataParser parser = convertingCache[i]; - if (parser != null) + DataConverter converter = convertingCache[i]; + if (converter != null) { double t0 = System.nanoTime(); - str = (CharSequence) ((DataConverter) parser).toString(new StringBuilder(), this, obj, args); + str = (CharSequence) converter.toString(new StringBuilder(), this, obj, args); double t = System.nanoTime(); if (str != SerializationDebugger.CONTINUE) { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + iterationStackTrace.put(iterationIndex, "[" + i + "] " + converter + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); return source.append(str); } } @@ -88,7 +88,7 @@ public Appendable toString(Appendable source, Object obj, Object... args) throws if(str != SerializationDebugger.CONTINUE) { if (convertingCache != null && i < convertingCache.length) - convertingCache[i] = parser; + convertingCache[i] = (DataConverter) parser; iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); return source.append(str); } diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 9667382..a1ba120 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -204,8 +204,7 @@ protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, E { if (format != 0) source.append(multilpy('\t', tabs)); - parsersToUse.toString(source, varToSerialize, args); - if (isLast) + if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) return source; return source.append(','); } @@ -215,8 +214,7 @@ protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, O { if (format != 0) source.append(multilpy('\t', tabs)); - parsersToUse.toString(source, objToSerialize, args); - if (isLast /*|| serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1*/) + if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) return source; return source.append(','); } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 927de3a..07ab3f6 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -401,8 +401,7 @@ protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, E { if (format != 0) source.append(multilpy('\t', tabs)); - parsersToUse.toString(source, varToSerialize, args); - if (isLast) + if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) return source; return source.append(';'); } @@ -416,8 +415,7 @@ protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, O { if (format != 0) source.append(multilpy('\t', tabs)); - parsersToUse.toString(source, objToSerialize, args); - if (isLast /*|| serializedVal != null && indexOfNotInObj(serializedVal, "//") != -1*/) + if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) return source; return source.append(';'); } diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 06e3299..e44ec12 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -3,19 +3,14 @@ import static org.ugp.serialx.Utils.indexOfNotInObj; import java.io.IOException; -import java.io.Serializable; import java.io.StringReader; import java.util.Arrays; -import java.util.Base64; import org.ugp.serialx.GenericScope; import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.ProtocolConverter; -import org.ugp.serialx.converters.SerializableBase64Converter; -import org.ugp.serialx.converters.DataParser.ParserRegistry; import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.juss.JussSerializer; import org.ugp.serialx.protocols.SerializationProtocol; @@ -64,18 +59,6 @@ new Scope( ... ) */ public class ObjectConverter extends ProtocolConverter { - /** - * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. - * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) - */ - protected boolean useBase64IfCan = false; - @SuppressWarnings("unchecked") @Override public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) @@ -142,18 +125,6 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj return toString(source, myHomeRegistry, obj, null, args); } - /** - * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param obj | Object to convert into string! - * @param preferedProtocol | Protocol to use preferably. - * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! - * - * @return The source appendable after stringified object (obj) was appropriately appended into it. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! - * - * @since 1.3.5 - */ @SuppressWarnings("unchecked") public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { From b019a3450d39cfad5d489505beb5a1e029d851c2 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 2 Aug 2025 21:30:10 +0200 Subject: [PATCH 61/75] ... --- .../main/java/org/ugp/serialx/converters/DataConverter.java | 5 +++-- .../src/main/java/org/ugp/serialx/converters/DataParser.java | 5 +++-- .../java/org/ugp/serialx/converters/ProtocolConverter.java | 3 +-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 28ab4c0..4a7ec15 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -20,7 +20,7 @@ public interface DataConverter extends DataParser * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! * * @since 1.3.0 */ @@ -44,7 +44,8 @@ default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Note: It is highly discouraged to append into this return! * * @throws IOException When appending into source throws it... * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index cf99076..6567e72 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -34,7 +34,7 @@ public interface DataParser * * @since 1.3.0 */ - public static final Appendable CONTINUE = new StringBuilder(); + public static final Appendable CONTINUE = new StringBuilder(0); /** * This is DataParser registry. Here your parser implementations should be registered in order to work properly! @@ -186,7 +186,8 @@ public CharSequence toString(Object obj, Object... args) * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! * * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Note: It is highly discouraged to append into this return! * * @throws IOException When appending into source throws it... * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 300c8b8..10e1680 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -179,8 +179,7 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj * @param preferedProtocol | Protocol to use preferably. * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! * - * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. - * Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * @return In accordance with {@link DataConverter#toString(Appendable, org.ugp.serialx.converters.DataParser.ParserRegistry, Object, Object...)}. * * @since 1.3.5 */ From ded1c7fb4dce18fcf3b1a9ccd7bb61d0206ba79c Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 2 Aug 2025 23:36:41 +0200 Subject: [PATCH 62/75] append null if no converter found... --- .../main/java/org/ugp/serialx/converters/DataConverter.java | 1 - .../src/main/java/org/ugp/serialx/converters/DataParser.java | 5 ++--- .../src/main/java/org/ugp/serialx/json/JsonSerializer.java | 1 - .../src/main/java/org/ugp/serialx/juss/JussSerializer.java | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index 4a7ec15..ff9bf24 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -24,7 +24,6 @@ public interface DataConverter extends DataParser * * @since 1.3.0 */ - @Deprecated default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) { try diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 6567e72..78c1695 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -153,7 +153,7 @@ public DataParser getParserFor(String str, Object... args) public DataConverter getConverterFor(Object obj, Object... args) { for (DataParser parser : this) - if (parser instanceof DataConverter && ((DataConverter)parser).toString(this, obj, args) != CONTINUE) + if (parser instanceof DataConverter && ((DataConverter) parser).toString(this, obj, args) != CONTINUE) return (DataConverter) parser; return null; } @@ -167,7 +167,6 @@ public DataConverter getConverterFor(Object obj, Object... args) * * @since 1.3.5 */ - @Deprecated public CharSequence toString(Object obj, Object... args) { try @@ -213,7 +212,7 @@ public Appendable toString(Appendable source, Object obj, Object... args) throws } LogProvider.instance.logErr("Unable to convert \"" + (obj == null ? "null" : obj.getClass().getName()) + "\" to string because none of registered converters were aplicable for this object!", null); - return null; + return source.append("null"); } /** diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index a1ba120..8614966 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -1,6 +1,5 @@ package org.ugp.serialx.json; -import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.isOneOf; import static org.ugp.serialx.Utils.multilpy; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 07ab3f6..7e46453 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -3,7 +3,6 @@ import static org.ugp.serialx.Utils.Clone; import static org.ugp.serialx.Utils.ENDL; import static org.ugp.serialx.Utils.InvokeStaticFunc; -import static org.ugp.serialx.Utils.indexOfNotInObj; import static org.ugp.serialx.Utils.isOneOf; import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.converters.DataParser.VOID; From 5ae1592935ad7e5307d447a944dcfe80ec482942 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 3 Aug 2025 00:01:41 +0200 Subject: [PATCH 63/75] small security enhancment... --- .../main/java/org/ugp/serialx/converters/ProtocolConverter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 10e1680..6f6344c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -72,7 +72,7 @@ public class ProtocolConverter implements DataConverter */ protected boolean useBase64IfCan = false; - protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, Scope.class, Double.class, Float.class, String.class)); + protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, GenericScope.class, Double.class, Float.class, String.class)); protected long protocolType = 0; From b201c72216192ff817c3f214b6c8005ec56a0f21 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 3 Aug 2025 23:34:34 +0200 Subject: [PATCH 64/75] docs and mem optimizations... --- .../main/java/org/ugp/serialx/Serializer.java | 26 +++++++++++++++---- .../protocols/SerializationProtocol.java | 4 +++ .../org/ugp/serialx/juss/JussSerializer.java | 2 +- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index e50f1be..1e7037a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -254,7 +254,7 @@ public String Code(Object code) * * @see Serializer#stringify(Object...) */ - public String toString(boolean serialize) throws IOException + public String toString(boolean serialize) { if (serialize) return stringify(); @@ -290,7 +290,7 @@ public void serializeTo(boolean append, File f, Object... args) throws IOExcepti //double t0 = System.nanoTime(); Writer writer = new BufferedWriter(new FileWriter(f, append)); - writer.write(stringify(args)); + serializeTo(writer, args); writer.close(); @@ -314,13 +314,22 @@ public void serializeTo(boolean append, File f, Object... args) throws IOExcepti * * @return String with objects serialized in specific format. * + * @throws RuntimeException IOException, but it should not occur in this case... + * * @since 1.0.0 * * @see Serializer#serializeTo(Appendable, Object...) */ - public String stringify(Object... args) throws IOException + public String stringify(Object... args) { - return serializeTo(new StringBuilder(), args).toString(); + try + { + return serializeTo(new StringBuilder(), args).toString(); + } + catch (IOException e) + { + throw new RuntimeException(e); // Should not occur... + } } /** @@ -329,6 +338,8 @@ public String stringify(Object... args) throws IOException * * @return Source {@link OutputStream} with variables and objects serialized in specific format (may or may not be flushed). * + * @throws IOException When appending the {@link OutputStream} throws.... + * * @since 1.3.2 * * @see Serializer#serializeTo(Appendable, Object...) @@ -434,6 +445,8 @@ public S loadFrom(Reader reader) throws IOException /** * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! * + * @throws Exception When creating the new instance fails... + * * @since 1.3.2 */ public Serializer emptyClone() throws Exception @@ -446,6 +459,8 @@ public Serializer emptyClone() throws Exception * * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! * + * @throws Exception When creating the new instance fails... + * * @since 1.3.2 */ public Serializer emptyClone(Scope parent) throws Exception @@ -458,7 +473,8 @@ public Serializer emptyClone(Scope parent) throws Exception * @param parent | Parent scope of new Serializer instance! * * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! - * @throws Exception + * + * @throws Exception When creating the new instance fails... * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 2babf3b..065686b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -171,6 +171,8 @@ public void setActive(boolean isActive) * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from {@link SerializationProtocol#REGISTRY}. * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! * + * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. + * * @since 1.3.0 */ public static Object[] serializeObj(O object) throws Exception @@ -186,6 +188,8 @@ public static Object[] serializeObj(O object) throws Exception * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from registry. * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! * + * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. + * * @since 1.3.0 */ public static Object[] serializeObj(ProtocolRegistry registry, long aditionalType, O object) throws Exception diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 7e46453..10faa07 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -949,7 +949,7 @@ Obtained serializer content (return) * - * @throws If something went wrong during deserialization! + * @throws Exception If something went wrong during deserialization! * * @since 1.3.5 */ From c06f1ecdd21fe0a38c945ac1799872186b9adea5 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 4 Aug 2025 00:50:35 +0200 Subject: [PATCH 65/75] fixing javadocs... --- .../src/main/java/org/ugp/serialx/Serializer.java | 2 +- .../java/org/ugp/serialx/converters/DataParser.java | 2 +- .../org/ugp/serialx/converters/ProtocolConverter.java | 10 +++++----- .../converters/SerializableBase64Converter.java | 2 +- .../org/ugp/serialx/converters/StringConverter.java | 9 ++++----- .../org/ugp/serialx/converters/VariableParser.java | 2 +- .../main/java/org/ugp/serialx/juss/JussSerializer.java | 10 +++++----- .../ugp/serialx/juss/converters/VariableConverter.java | 8 ++++---- .../juss/protocols/SelfSerializableProtocol.java | 2 +- .../converters/operators/ArithmeticOperators.java | 2 +- 10 files changed, 24 insertions(+), 25 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 1e7037a..530e56d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -737,7 +737,7 @@ public void setFormat(byte format) {@link File} - {@link Serializer#serializeTo(File)} + {@link Serializer#serializeTo(File, Object...)} {@link Appendable} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 78c1695..538af91 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -46,7 +46,7 @@ public interface DataParser public static final ParserRegistry REGISTRY = new ParserRegistry(new VariableParser(), new StringConverter(), new ProtocolConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link DataParser#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! * @param str | Source string, preferably trimed! * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 6f6344c..0c9d899 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -68,7 +68,7 @@ public class ProtocolConverter implements DataConverter * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
* Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ObjectConverter}) + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ProtocolConverter}) */ protected boolean useBase64IfCan = false; @@ -95,7 +95,7 @@ public Object parse(ParserRegistry myHomeRegistry, String str, Object... compile /** * @param myHomeRegistry | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. * @param objClass | Class of object to parse using {@link SerializationProtocol}. - * @param str | String that starts with {@link Class} of object to deserialized (it will be used with {@link SerializationProtocol#unserializeObj(ProtocolRegistry, Class, Object...)}). + * @param str | String that starts with {@link Class} of object to deserialized (it will be used with {@link SerializationProtocol#unserializeObj(ProtocolRegistry, long, Class, Object...)}). * @param compilerArgs | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. * * @return Object od objClass parsed from str in accordance with compilerArgs! @@ -108,7 +108,7 @@ protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String { StringBuilder sb = new StringBuilder(str); sb.setCharAt(str.indexOf(' '), '='); - return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ObjectConverter and VariableConverter are present... + return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ProtocolConverter and VariableConverter are present... } if (compilerArgs.length < 5) @@ -331,7 +331,7 @@ public Set> getInvokableClasses() * @param args | Parser args to get protocol from! * * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
- * Note: This is mainly used by {@link ObjectConverter}! + * Note: This is mainly used by {@link ProtocolConverter}! * * @since 1.3.5 */ @@ -449,7 +449,7 @@ public static Object InvokeStaticFunc(Class cls, Class oldCls, String name } /** - * Used internally by {@link ObjectConverter}!
+ * Used internally by {@link ProtocolConverter}!
* Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: * * shortenedSelectorLikeScope {

diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index 14c1d61..449ca0d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -39,7 +39,7 @@ new ArrayList() new int[] {5, 5, 5} - * Note: In most of the cases {@link ObjectConverter} and {@link SerializationProtocol} should be used as preferable alternative!
+ * Note: In most of the cases {@link SerializationProtocol} and therefore {@link ProtocolConverter} should be used as preferable alternative!
* Note: In order to avoid conflicts with JUSS syntax, this converter serializes and deserializes by using {@link Base64} and {@link URLEncoder} with addition of all % are being replaced by #! * * @author PETO diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 1628c92..6bbf40b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -4,10 +4,9 @@ import static org.ugp.serialx.Utils.indexOfNotInObj; import java.io.IOException; +import java.util.HashMap; import java.util.Map; -import org.ugp.serialx.Registry; - /** * This converter is capable of converting {@link String}. * Its case sensitive! @@ -30,7 +29,7 @@ new String("Hello world!") - * If you enter string in ${yourString}, "yourString" will be returned by {@link StringConverter#toString(Registry, Object, Object...)} according to {@link StringConverter#CodeInsertion(String)}! + * If you enter string in ${yourString}, "yourString" will be returned by {@link StringConverter#toString} according to {@link StringConverter#DirectCode}! * * @author PETO * @@ -155,9 +154,9 @@ public void setSerializeStringNormally(boolean serializeStringNormally) } /** - * @param obj | Object to stringify directly. + * @param obj | Object to stringify directly (without formating it as string). * - * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString(Registry, Object, Object...)}, it will be returned without ${ and }! + * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString}, it will be returned without ${ and }! * * @since 1.3.5 */ diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 9d82ce3..e3199a3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -10,7 +10,7 @@ /** * This parser is capable of reading variables from {@link GenericScope} by using $!
- * {@link VariableParser#parse(String, Object...)} requires one additional Scope argument in args... at index 0!
+ * {@link VariableParser#parse} requires one additional Scope argument in args... at index 0!
* It also manages access member operator also known as separator ".".
* Its case sensitive!
* Exact outputs of this converter are based on inserted scope! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index 10faa07..f0c946c 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -192,7 +192,7 @@ public Imports getImports() } /** - * @param absoluteClone | If true this scope will be cloned using {@link Serializer#Clone(Object, Registry, Object[], Object...)}, if false {@link Scope#clone()}! + * @param absoluteClone | If true this scope will be cloned using {@link Utils#Clone}, if false {@link Scope#clone()}! * * @return Clone of this scope! * @@ -622,7 +622,7 @@ else if (ch <= ' ') // Handle blanks, skip unnecessary } /** - * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, Object...)} INSTEAD! + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! * * @return Formated content of reader ready to parse! Should not modify this object in any way! * @@ -710,7 +710,7 @@ else if (ch == '}' || ch == ']') } /** - * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, Object...)} INSTEAD! + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! * * @return List of objects parsed from given formatted string! * @@ -791,9 +791,9 @@ else if (ch == '"') /** * @return Object parsed from str! *

- * Note: Used by {@link JussSerializer#splitAndParse(String, int, Object...)}! + * Note: Used by {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)}! * - * @see DataParser#parseObj(Registry, String, Object...) + * @see ParserRegistry#parse(ParserRegistry, String, Object...) * * @since 1.3.2 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index e060202..555fa62 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -15,7 +15,7 @@ /** * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using $!
- * {@link VariableConverter#parse(String, Object...)} requires one additional Scope argument in args... at index 0!
+ * {@link VariableConverter#parse} requires one additional Scope argument in args... at index 0!
* It manages assign operator = as well as access member operator also known as separator ".".
* Its case sensitive!
* Exact outputs of this converter are based on inserted scope! @@ -38,7 +38,7 @@ public VariableConverter() /** * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * ORMATING IS NO DONE IN toString FUNCTION! * * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! * @@ -188,7 +188,7 @@ public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, St /** * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * ORMATING IS NO DONE IN toString FUNCTION! * * @return True if variables will be serialized using json style ("key" : value)! * @@ -202,7 +202,7 @@ public boolean isJsonStyle() /** * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * FORMATING IS NO DONE IN {@link VariableConverter#appendEntry(StringBuilder, CharSequence, Object, Object...)} + * FORMATING IS NO DONE IN toString FUNCTION! * * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! * diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index 68d15c0..e1d3495 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -15,7 +15,7 @@ public class SelfSerializableProtocol extends Univer { /** * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
- * Note: Passing {@link SelfSerializable#getClass()} will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered unsafe in some cases... + * Note: Passing {@link SelfSerializable}.class will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered a security risk in some cases... * * @since 1.3.8 */ diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 1845902..e807698 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -23,7 +23,7 @@ public class ArithmeticOperators implements DataParser { /** - * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator(Object, String, Object)}.
Intended for override, should not be null or empty! + * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator}.
Intended for override, should not be null or empty! * * @since 1.3.8 */ From cf32aa4efc482af2d37a3b83def3fbcb4e1cdae3 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 6 Aug 2025 23:13:23 +0200 Subject: [PATCH 66/75] dev-tools 1.3.9... --- SerialX-devtools/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index 872b6ba..e98d18c 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-devtools - 1.3.8 + 1.3.9 SerialX devtools Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. From 39efb143eb6cfb3f6e56c059bfef2a8b2f337ca2 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Fri, 8 Aug 2025 16:36:24 +0200 Subject: [PATCH 67/75] 4.0.0 init, MultimediaSerializer and .utils pkg --- SerialX-core/pom.xml | 2 +- .../java/org/ugp/serialx/GenericScope.java | 4 +- .../org/ugp/serialx/MultimediaSerializer.java | 216 ++++++++++++++++++ .../src/main/java/org/ugp/serialx/Scope.java | 6 +- .../main/java/org/ugp/serialx/Serializer.java | 214 +---------------- .../serialx/converters/BooleanConverter.java | 2 +- .../ugp/serialx/converters/DataParser.java | 4 +- .../ugp/serialx/converters/NullConverter.java | 2 +- .../serialx/converters/NumberConverter.java | 2 +- .../serialx/converters/ProtocolConverter.java | 8 +- .../SerializableBase64Converter.java | 2 +- .../serialx/converters/StringConverter.java | 4 +- .../serialx/converters/VariableParser.java | 6 +- .../ugp/serialx/protocols/MapProtocol.java | 2 +- .../protocols/SerializationProtocol.java | 4 +- .../ugp/serialx/{ => utils}/LogProvider.java | 2 +- .../org/ugp/serialx/{ => utils}/Registry.java | 2 +- .../org/ugp/serialx/{ => utils}/Utils.java | 4 +- SerialX-devtools/pom.xml | 4 +- .../serialx/devtools/DebugParserRegistry.java | 2 +- .../devtools/SerializationDebugger.java | 4 +- SerialX-json/pom.xml | 4 +- .../org/ugp/serialx/json/JsonSerializer.java | 6 +- .../json/converters/JsonObjectConverter.java | 2 +- SerialX-juss/pom.xml | 4 +- .../org/ugp/serialx/juss/JussSerializer.java | 16 +- .../juss/converters/ArrayConverter.java | 8 +- .../juss/converters/ImportConverter.java | 2 +- .../juss/converters/ObjectConverter.java | 4 +- .../juss/converters/OperationGroups.java | 8 +- .../juss/converters/VariableConverter.java | 6 +- .../serialx/juss/protocols/AutoProtocol.java | 2 +- .../UniversalObjectInstantiationProtocol.java | 4 +- SerialX-operators/pom.xml | 4 +- .../operators/ArithmeticOperators.java | 4 +- .../operators/ComparisonOperators.java | 4 +- .../ConditionalAssignmentOperators.java | 4 +- .../operators/LogicalOperators.java | 6 +- .../operators/NegationOperator.java | 2 +- pom.xml | 2 +- 40 files changed, 304 insertions(+), 284 deletions(-) create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java rename SerialX-core/src/main/java/org/ugp/serialx/{ => utils}/LogProvider.java (98%) rename SerialX-core/src/main/java/org/ugp/serialx/{ => utils}/Registry.java (99%) rename SerialX-core/src/main/java/org/ugp/serialx/{ => utils}/Utils.java (99%) diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index e92f136..8d4a47d 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-core - 1.3.9 + 4.0.0-SNAPSHOT SerialX core Core of SerialX. Contains core features and utilities shared across the library. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index e9b1cde..f2583a8 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -1,6 +1,6 @@ package org.ugp.serialx; -import static org.ugp.serialx.Utils.Instantiate; +import static org.ugp.serialx.utils.Utils.Instantiate; import java.io.Serializable; import java.lang.reflect.Type; @@ -20,6 +20,8 @@ import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java b/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java new file mode 100644 index 0000000..4b38dd8 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java @@ -0,0 +1,216 @@ +package org.ugp.serialx; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.util.Collection; +import java.util.Map; + +/** + * Interface with common methods for serializing and deserializing/loading contents from various types of media ({@link File}, {@link InputStream}, {@link Appendable}, {@link Reader} etc...).
+ * Intended/recommended use is to implement this together with some sort of {@link Collection} or {@link Map} and/or something that can be treated as such. + * + * @param Type of the object that is serialized and deserialized, you likely want this to be the class (or patent class) of an implementor of this interface. + * + * @author PETO + * + * @since 4.0.0 (Separated from {@link Serializer} in 4.0.0) + */ +public interface MultimediaSerializer +{ + /** + * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + */ + default void serializeTo(File f, Object... args) throws IOException + { + serializeTo(false, f, args); + } + + /** + * @param append | When true, the new objects will be appended to files content (same objects will be also appended if there are some)! + * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default void serializeTo(boolean append, File f, Object... args) throws IOException + { + //double t0 = System.nanoTime(); + try (Writer writer = new BufferedWriter(new FileWriter(f, append))) + { + serializeTo(writer, args); + } + +// String serialized = stringify(args); +// +// RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); +// FileChannel channel = fileOutputStream.getChannel(); +// +//// channel.write(ByteBuffer.wrap(serialized.getBytes())); +// +// ByteBuffer buff = channel.map(FileChannel.MapMode.READ_WRITE, append ? channel.size() : 0, serialized.length()); +// buff.put(serialized.getBytes()); +// +// channel.force(true); +// channel.close(); +// fileOutputStream.close(); + } + + /** + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return String with the respective contents serialized in specific format. + * + * @throws RuntimeException IOException, but it should not occur in this case... + * + * @since 1.0.0 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default String stringify(Object... args) + { + try + { + return serializeTo(new StringBuilder(), args).toString(); + } + catch (IOException e) + { + throw new RuntimeException(e); // Should not occur... + } + } + + /** + * @param outputStream | Source {@link OutputStream} to serialize the respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link OutputStream} with respective contents serialized in specific format (may or may not be flushed). + * + * @throws IOException When appending the {@link OutputStream} throws.... + * + * @since 1.3.2 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default OutputStream serializeTo(OutputStream outputStream, Object... args) throws IOException + { + serializeTo(new OutputStreamWriter(outputStream), args); + return outputStream; + } + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link Appendable} with respective contents serialized in specific format (depends on the implementation). + * + * @throws IOException depends on the implementation (likely when the provided source throws). + * + * @since 1.3.2 + */ + A serializeTo(A source, Object... args) throws IOException; + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. + * + * @since 1.3.5 + */ + default A serializeAsSubscope(A source, Object... args) throws IOException + { + return serializeAsSubscope(source, new char[] {'{', '}'}, args); + } + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param wrappingBrackets | Array of 2 characters to wrap content inside (opening and closing one). + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. + * + * @since 1.3.5 + */ + A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException; + + /** + * @param file | Text file with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException if file does not exist or cannot be read! + * + * @since 1.0.0 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(File file, Object... parserArgs) throws IOException + { + return loadFrom(new FileReader(file), parserArgs); + } + + /** + * @param str | {@link CharSequence} with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException When reading the char sequence fails... + * + * @since 1.2.5 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(CharSequence str, Object... parserArgs) throws IOException + { + return loadFrom(new StringReader(str.toString()), parserArgs); + } + + /** + * @param stream | Any {@link InputStream} with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException When reading the input stream fails... + * + * @since 1.3.2 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(InputStream stream, Object... parserArgs) throws IOException + { + return loadFrom(new InputStreamReader(stream), parserArgs); + } + + /** + * @param reader | Reader to read the with serialized contents from! + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this". If T is instanceof this Class, you most likely want to return "this")! + * + * @throws IOException When reading the reader fails... + * + * @since 1.3.2 + */ + S loadFrom(Reader reader, Object... parserArgs) throws IOException; +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index 69b6b0d..df60437 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1,8 +1,8 @@ package org.ugp.serialx; -import static org.ugp.serialx.Utils.Instantiate; -import static org.ugp.serialx.Utils.equalsLowerCase; import static org.ugp.serialx.converters.DataParser.VOID; +import static org.ugp.serialx.utils.Utils.Instantiate; +import static org.ugp.serialx.utils.Utils.equalsLowerCase; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -24,6 +24,8 @@ import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index 530e56d..de37137 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -1,25 +1,17 @@ package org.ugp.serialx; -import static org.ugp.serialx.Utils.Instantiate; -import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.multilpy; -import static org.ugp.serialx.Utils.post; +import static org.ugp.serialx.utils.Utils.Instantiate; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.Utils.post; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; -import java.io.BufferedWriter; import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; -import java.io.OutputStreamWriter; import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; import java.lang.reflect.Type; import java.net.HttpURLConnection; import java.net.URI; @@ -37,6 +29,8 @@ import org.ugp.serialx.converters.StringConverter; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; /** * {@link org.ugp.serialx.Serializer} is powerful abstract class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s. @@ -48,7 +42,7 @@ * @since 1.0.0 */ @SuppressWarnings("serial") -public abstract class Serializer extends Scope +public abstract class Serializer extends Scope implements MultimediaSerializer { /** * Common parsers that can parse primitive datatypes! @@ -261,187 +255,6 @@ public String toString(boolean serialize) return super.toString(); } - /** - * @param f | File to write in. This must be a text file. - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @throws IOException if file can't be opened or serialization fails! - * - * @since 1.1.5 - */ - public void serializeTo(File f, Object... args) throws IOException - { - serializeTo(false, f, args); - } - - /** - * @param append | When true, the new objects will be appended to files content (same objects will be also appended if there are some)! - * @param f | File to write in. This must be a text file. - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @throws IOException if file can't be opened or serialization fails! - * - * @since 1.1.5 - * - * @see Serializer#serializeTo(Appendable, Object...) - */ - public void serializeTo(boolean append, File f, Object... args) throws IOException - { - //double t0 = System.nanoTime(); - Writer writer = new BufferedWriter(new FileWriter(f, append)); - - serializeTo(writer, args); - - writer.close(); - -// String serialized = stringify(args); -// -// RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); -// FileChannel channel = fileOutputStream.getChannel(); -// -//// channel.write(ByteBuffer.wrap(serialized.getBytes())); -// -// ByteBuffer buff = channel.map(FileChannel.MapMode.READ_WRITE, append ? channel.size() : 0, serialized.length()); -// buff.put(serialized.getBytes()); -// -// channel.force(true); -// channel.close(); -// fileOutputStream.close(); - } - - /** - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return String with objects serialized in specific format. - * - * @throws RuntimeException IOException, but it should not occur in this case... - * - * @since 1.0.0 - * - * @see Serializer#serializeTo(Appendable, Object...) - */ - public String stringify(Object... args) - { - try - { - return serializeTo(new StringBuilder(), args).toString(); - } - catch (IOException e) - { - throw new RuntimeException(e); // Should not occur... - } - } - - /** - * @param outputStream | Source {@link OutputStream} to serialize variables and objects into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Source {@link OutputStream} with variables and objects serialized in specific format (may or may not be flushed). - * - * @throws IOException When appending the {@link OutputStream} throws.... - * - * @since 1.3.2 - * - * @see Serializer#serializeTo(Appendable, Object...) - */ - public OutputStream serializeTo(OutputStream outputStream, Object... args) throws IOException - { - serializeTo(new OutputStreamWriter(outputStream), args); - return outputStream; - } - - /** - * @param source | Source {@link Appendable} to serialize variables and objects into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Source {@link Appendable} with variables and objects serialized in specific format. - * - * @throws IOException depends on the implementation (likely when the provided source throws). - * - * @since 1.3.2 - */ - public abstract A serializeTo(A source, Object... args) throws IOException; - - /** - * @param file | Text file with serialized objects in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. - * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! - * - * @throws FileNotFoundException if file does not exist or cannot be read! - * - * @since 1.0.0 - * - * @see Serializer#loadFrom(Reader, Object...) - */ - public S loadFrom(File file, Object... parserArgs) throws IOException - { - return loadFrom(new FileReader(file), parserArgs); - } - - /** - * @param str | {@link CharSequence} with serialized objects in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. - * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! - * - * @throws IOException When reading the char sequence fails... - * - * @since 1.2.5 - * - * @see Serializer#loadFrom(Reader, Object...) - */ - public S loadFrom(CharSequence str, Object... parserArgs) throws IOException - { - return loadFrom(new StringReader(str.toString()), parserArgs); - } - - /** - * @param stream | Any {@link InputStream} with serialized objects in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized objects and variables in {@link Scope} or empty {@link Scope} if string is empty. - * You can use negative indexes to get objects from back of this array since 1.1.0 (-1 = last element)! - * - * @throws IOException When reading the input stream fails... - * - * @since 1.3.2 - * - * @see Serializer#loadFrom(Reader, Object...) - */ - public S loadFrom(InputStream stream, Object... parserArgs) throws IOException - { - return loadFrom(new InputStreamReader(stream), parserArgs); - } - - /** - * @param reader | Any {@link Reader} with serialized objects in specific format to load. - * - * @return This scope after loading data from reader (you most likely want to return "this")! - * - * @throws IOException When reading the reader fails... - * - * @since 1.2.5 - */ - public S loadFrom(Reader reader) throws IOException - { - return loadFrom(reader, true); - } - - /** - * @param reader | Reader to read from! - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return This scope after loading data from reader (you most likely want to return "this")! - * - * @throws IOException When reading the reader fails... - * - * @since 1.3.2 - */ - public abstract S loadFrom(Reader reader, Object... parserArgs) throws IOException; - /** * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! * @@ -621,19 +434,6 @@ public Object apply(Object t) return (GenericScope) transform(transFunction); } - /** - * @param source | Source {@link Appendable} to serialize variables and objects into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Serialized content of this scope as inner sub-scope of this scope! Wrapped inside of corresponding wrappingBrackets (default { and })! - * - * @since 1.3.5 - */ - public A serializeAsSubscope(A source, Object... args) throws IOException - { - return serializeAsSubscope(source, new char[] {'{', '}'}, args); - } - /** * @param source | Source {@link Appendable} to serialize variables and objects into! * @param wrappingBrackets | Array of 2 characters to wrap content inside diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index a60c9c3..be2ba92 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters; import static java.lang.Boolean.*; -import static org.ugp.serialx.Utils.equalsLowerCase; +import static org.ugp.serialx.utils.Utils.equalsLowerCase; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 538af91..be49a73 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -3,9 +3,9 @@ import java.io.IOException; import java.util.Collection; -import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; /** * This interface is supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index ffb381e..2b7ae79 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.equalsLowerCase; +import static org.ugp.serialx.utils.Utils.equalsLowerCase; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 31588dd..3442d97 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.contains; +import static org.ugp.serialx.utils.Utils.contains; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 0c9d899..defac7f 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -1,8 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.*; -import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.splitValues; +import static org.ugp.serialx.utils.Utils.*; import java.io.IOException; import java.io.Serializable; @@ -14,13 +12,13 @@ import java.util.Set; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.Utils; import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; /** * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index 449ca0d..71fe69e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -10,8 +10,8 @@ import java.net.URLEncoder; import java.util.Base64; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.LogProvider; /** * This converter is capable of converting {@link Serializable}. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 6bbf40b..2985f7c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; import java.io.IOException; import java.util.HashMap; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index e3199a3..71bf137 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -1,8 +1,8 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.Utils.Clone; -import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.splitValues; +import static org.ugp.serialx.utils.Utils.Clone; +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.splitValues; import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java index eacd7ee..90b46b3 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java @@ -6,7 +6,7 @@ import java.util.Map.Entry; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; +import org.ugp.serialx.utils.LogProvider; /** * ListProtocol is universal protocol to serialize any {@link Map} instance. The condition of use is public constructor with one {@link Map} argument. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index 065686b..f6f73e6 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -5,9 +5,9 @@ import java.util.Collection; import java.util.List; -import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Registry; import org.ugp.serialx.Serializer; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; /** * This class supposed to be used for serializing and unserializing objects in Java by turning them in to array of Objects that can be serialized by {@link Serializer} or used by some higher entities. Also this class is capable of turning array of these objects back in to that very same Object!
diff --git a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java similarity index 98% rename from SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java rename to SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java index b68d533..f4fc843 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/LogProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java @@ -1,4 +1,4 @@ -package org.ugp.serialx; +package org.ugp.serialx.utils; /** * Log provider used for logging in SerialX. diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java similarity index 99% rename from SerialX-core/src/main/java/org/ugp/serialx/Registry.java rename to SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java index b0cde1b..8e6db5d 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Registry.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java @@ -1,4 +1,4 @@ -package org.ugp.serialx; +package org.ugp.serialx.utils; import java.util.ArrayList; import java.util.Collection; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java similarity index 99% rename from SerialX-core/src/main/java/org/ugp/serialx/Utils.java rename to SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java index 9f4922f..89a1939 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java @@ -1,4 +1,4 @@ -package org.ugp.serialx; +package org.ugp.serialx.utils; import static org.ugp.serialx.converters.DataParser.VOID; @@ -21,6 +21,8 @@ import java.util.List; import java.util.Map; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index e98d18c..a6eba2a 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-devtools - 1.3.9 + 4.0.0-SNAPSHOT SerialX devtools Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - 1.3.9 + 4.0.0-SNAPSHOT \ No newline at end of file diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index fd390d5..37b5116 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -4,10 +4,10 @@ import java.util.Map; import java.util.TreeMap; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.utils.LogProvider; /** * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index 8f80171..bd2dc59 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -1,6 +1,6 @@ package org.ugp.serialx.devtools; -import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.utils.Utils.multilpy; import java.io.IOException; import java.io.PrintWriter; @@ -9,10 +9,10 @@ import java.util.Map; import java.util.Map.Entry; -import org.ugp.serialx.Registry; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.Registry; /** * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 3705816..0f75afb 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-json - 1.3.9 + 4.0.0-SNAPSHOT SerialX json SerialX Json support @@ -19,7 +19,7 @@ org.ugp.serialx serialx-juss - 1.3.9 + 4.0.0-SNAPSHOT \ No newline at end of file diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 8614966..008520c 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -1,7 +1,7 @@ package org.ugp.serialx.json; -import static org.ugp.serialx.Utils.isOneOf; -import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.utils.Utils.isOneOf; +import static org.ugp.serialx.utils.Utils.multilpy; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -18,7 +18,6 @@ import java.util.Map.Entry; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.BooleanConverter; @@ -33,6 +32,7 @@ import org.ugp.serialx.juss.JussSerializer; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.Registry; /** * This is implementation of {@link JussSerializer} for serializing in
Json! diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index c66bb21..62a55f5 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -5,10 +5,10 @@ import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.Utils; import org.ugp.serialx.json.JsonSerializer; import org.ugp.serialx.juss.converters.ObjectConverter; import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.Utils; /** * Used internally by {@link JsonSerializer} to ensure proper and valid Json format for scopes and protocols. diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index a1088c7..74a5921 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-juss - 1.3.9 + 4.0.0-SNAPSHOT SerialX juss SerialX support for Java Universal Serial Script data format, custom default format of SerialX! @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - 1.3.9 + 4.0.0-SNAPSHOT \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index f0c946c..ecb6614 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,11 +1,11 @@ package org.ugp.serialx.juss; -import static org.ugp.serialx.Utils.Clone; -import static org.ugp.serialx.Utils.ENDL; -import static org.ugp.serialx.Utils.InvokeStaticFunc; -import static org.ugp.serialx.Utils.isOneOf; -import static org.ugp.serialx.Utils.multilpy; import static org.ugp.serialx.converters.DataParser.VOID; +import static org.ugp.serialx.utils.Utils.Clone; +import static org.ugp.serialx.utils.Utils.ENDL; +import static org.ugp.serialx.utils.Utils.InvokeStaticFunc; +import static org.ugp.serialx.utils.Utils.isOneOf; +import static org.ugp.serialx.utils.Utils.multilpy; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -28,10 +28,8 @@ import java.util.Map.Entry; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Registry; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; -import org.ugp.serialx.Utils; import org.ugp.serialx.converters.BooleanConverter; import org.ugp.serialx.converters.CharacterConverter; import org.ugp.serialx.converters.DataConverter; @@ -48,6 +46,8 @@ import org.ugp.serialx.juss.converters.OperationGroups; import org.ugp.serialx.juss.converters.VariableConverter; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.Registry; +import org.ugp.serialx.utils.Utils; /** * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! @@ -477,7 +477,7 @@ public S loadFrom(Reader reader, Object... args) throws IOExce } /** - * This acts basically as a lexer for Juss and Json... + * This acts basically as reader + lexer for Juss and Json input... * * @param result | Resulting collection of objects to fill up with parsed objects from reader. * @param reader | The reader to {@link Reader#read(char[], int, int)}. diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 003a296..9deb550 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -1,9 +1,9 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.castArray; -import static org.ugp.serialx.Utils.fromAmbiguousArray; -import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.splitValues; +import static org.ugp.serialx.utils.Utils.castArray; +import static org.ugp.serialx.utils.Utils.fromAmbiguousArray; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.splitValues; import java.io.IOException; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java index 0104af6..7c50205 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java @@ -2,12 +2,12 @@ import java.io.IOException; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.imports.Import; import org.ugp.serialx.converters.imports.ImportsProvider; import org.ugp.serialx.converters.imports.ImportsProvider.Imports; +import org.ugp.serialx.utils.LogProvider; /** * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index e44ec12..5d79fa7 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -1,13 +1,12 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; import java.io.IOException; import java.io.StringReader; import java.util.Arrays; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.Serializer; import org.ugp.serialx.converters.ProtocolConverter; @@ -15,6 +14,7 @@ import org.ugp.serialx.juss.JussSerializer; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; /** * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index bce74f9..1314bf5 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -1,13 +1,13 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.isOneOf; +import static org.ugp.serialx.utils.Utils.isOneOf; import java.util.Arrays; import java.util.HashMap; import java.util.Map; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides ability to use expression groups that can define order of expression evaluation and compilation! @@ -111,7 +111,7 @@ public static int isGroupMark(CharSequence s, char groupMark) * @param from | Beginning index of search! * @param openings | Openings to find! * - * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.Utils#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ @@ -148,7 +148,7 @@ else if (isOneOf(ch, openings)) * @param openings | Openings to count with! * @param closing | Closings to find! * - * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.Utils#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 555fa62..558f5dc 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,7 +1,7 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.Utils.contains; -import static org.ugp.serialx.Utils.splitValues; +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.splitValues; import java.io.IOException; import java.util.AbstractMap; @@ -9,9 +9,9 @@ import java.util.Map.Entry; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataConverter; import org.ugp.serialx.converters.VariableParser; +import org.ugp.serialx.utils.LogProvider; /** * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using $!
diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index 9f72076..f5d3165 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -11,8 +11,8 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; -import org.ugp.serialx.Utils; import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.Utils; /** * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index d8df934..6c6fd69 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -5,9 +5,9 @@ import java.util.Arrays; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; -import org.ugp.serialx.Utils; import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; /** * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index 6a09189..9152893 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -10,7 +10,7 @@ org.ugp.serialx serialx-operators - 1.3.9 + 4.0.0-SNAPSHOT SerialX operators This modul contains basic operators contained in almost every programing language... @@ -19,7 +19,7 @@ org.ugp.serialx serialx-core - 1.3.9 + 4.0.0-SNAPSHOT \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index e807698..19012c1 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters.operators; import static java.util.Arrays.asList; -import static org.ugp.serialx.Utils.*; +import static org.ugp.serialx.utils.Utils.*; import java.util.ArrayList; import java.util.Collection; @@ -10,8 +10,8 @@ import java.util.ListIterator; import org.ugp.serialx.GenericScope; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides arithmetics operators to evaluate mathematical expressions such as 5 * 2 +-- 2 / 2 ** 2 % 4 = 10! diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 40d8e0b..39bbedd 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -1,16 +1,16 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; import java.lang.reflect.Array; import java.util.Collection; import java.util.Map; import java.util.Objects; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.Scope; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides comparison operators, > < >= <= == === != !=== and instanceof, to compare 2 objects! For example 6 > 5, 1 < 5 or 5 == 5 returns true! diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index a86a22c..d0f7a39 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -1,9 +1,9 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides conditional assignment operators more specially ternary and null coalescing! For example true ? "Yes" : "No" will return "Yes" and null ?? "Hello!" will return hello! diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index be0cbcd..250e907 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -2,11 +2,11 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import static org.ugp.serialx.Utils.indexOfNotInObj; -import static org.ugp.serialx.Utils.multilpy; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.multilpy; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides logical operators to evaluate boolean expressions such as false || true && true ^ false = true! diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java index 2f727bb..f5940ff 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -1,7 +1,7 @@ package org.ugp.serialx.converters.operators; -import org.ugp.serialx.LogProvider; import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; /** * This parser provides ability to negate stuff! For example !true returns false!
diff --git a/pom.xml b/pom.xml index cf0ebc3..5a705f3 100644 --- a/pom.xml +++ b/pom.xml @@ -64,7 +64,7 @@ 8 - 1.3.9 + 4.0.0-SNAPSHOT UTF-8 ${java.version} From 689f028fcc3bcf5697ddf95cf16062961e272e16 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sat, 27 Jun 2026 06:16:27 +0200 Subject: [PATCH 68/75] preps --- .../java/org/ugp/serialx/GenericScope.java | 21 ++++++++++++++-- .../ugp/serialx/converters/DataParser.java | 24 +++++++++++++------ 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index f2583a8..0a752e7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -466,6 +466,21 @@ public boolean addAll(@SuppressWarnings("unchecked") ValT... values) return addAll(Arrays.asList(values)); } + /** + * @param variables | Map of variables to put in. (Will use {@link Map#putAll(Map)}) + * + * @return This generic scope after the variables were added into it. + * + * @since 4.0.0 + */ + public GenericScope putAll(Map variables) + { + if (variables.isEmpty()) + return this; + variables().putAll(variables); + return this; + } + /** * @param values | Independent values to check. * @@ -800,8 +815,10 @@ public ValT removeVariable(KeyT variableKey) @Override public void clear() { - variables().clear(); - values().clear(); + if (variables != null) + variables.clear(); + if (values != null) + values.clear(); } /** diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index be49a73..07ddca4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -77,7 +77,7 @@ public static Object parseObj(String str, Object... args) * * @since 1.3.5 */ - public static class ParserRegistry extends Registry implements DataParser + public static class ParserRegistry extends Registry implements DataConverter { private static final long serialVersionUID = -2598324826689380752L; @@ -171,7 +171,7 @@ public CharSequence toString(Object obj, Object... args) { try { - return (CharSequence) toString(new StringBuilder(), obj, args); + return (CharSequence) toString(new StringBuilder(), this, obj, args); } catch (IOException e) { @@ -193,17 +193,26 @@ public CharSequence toString(Object obj, Object... args) * @since 1.3.9 */ public Appendable toString(Appendable source, Object obj, Object... args) throws IOException + { + return toString(source, this, obj, args); + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException { Appendable str; if (convertingCache != null) for (DataConverter parser : convertingCache) - if (parser != null && (str = parser.toString(source, this, obj, args)) != CONTINUE) + if (parser != null && (str = parser.toString(source, myHomeRegistry, obj, args)) != CONTINUE) return str; for (int i = 0, size = size(); i < size; i++) { DataParser parser = get(i); - if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, this, obj, args)) != CONTINUE) + if (myHomeRegistry == parser) // Registry is registered in itself, infinite recursion = not good skip + continue; + + if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, myHomeRegistry, obj, args)) != CONTINUE) { if (convertingCache != null && i < convertingCache.length) convertingCache[i] = (DataConverter) parser; @@ -254,7 +263,7 @@ public Object parse(String str, Object... args) /** * @param str | Source string to parse using suitable parser from registry. * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message in case of suitable parser not found! - * @param ignore | {@link DataParser} class to ignore! + * @param ignore | {@link DataParser} class to ignore (if not precached)! * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! * * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. @@ -267,7 +276,7 @@ public Object parse(String str, boolean returnAsStringIfNotFound, Class classOfParserToPrecache) if (parser == null) return ret; + if (parser == this) + LogProvider.instance.logErr("Warning: You are pre caching instance of this registry in itself, which can result in infinite recursion. Do not do this!", null); if (i < parsingCache.length) { @@ -394,6 +405,5 @@ public DataConverter[] getConverterCache() { return convertingCache; } - } } From 362638a4acdaac70c426298f959f47f7f2ce705e Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 27 Sep 2026 19:49:19 +0200 Subject: [PATCH 69/75] indexOfNotInObj javadoc improvments --- .../java/org/ugp/serialx/utils/Utils.java | 1880 ++++++++--------- 1 file changed, 940 insertions(+), 940 deletions(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java index 89a1939..72ce194 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java @@ -1,941 +1,941 @@ -package org.ugp.serialx.utils; - -import static org.ugp.serialx.converters.DataParser.VOID; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.HttpURLConnection; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.protocols.SerializationProtocol; - -/** - * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection. - * - * @author PETO - * - * @since 1.3.8 - */ -public final class Utils { - private Utils() {} - - /** - * {@link System#lineSeparator()} - * - * @since 1.3.9 - */ - public static final char[] ENDL = System.lineSeparator().toCharArray(); - - /** - * @param f | Source file. - * - * @return All lines from source file as string. - * @throws IOException - * - * @since 1.1.5 - */ - public static String LoadFileToString(File f) throws IOException - { - return LoadFileToString(f, 1); - } - - /** - * @param f | Source file. - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Content of file as string. - * @throws IOException - * - * @since 1.2.0 - */ - public static String LoadFileToString(File f, int endlMode) throws IOException - { - return StreamToString(new FileReader(f), endlMode); - } - - /** - * @param input | Input stream to read to string! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.5 - */ - public static String StreamToString(InputStream input, int endlMode) throws IOException - { - return StreamToString(new InputStreamReader(input), endlMode); - } - - /** - * @param input | Input reader! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.2 - */ - public static String StreamToString(Reader input, int endlMode) throws IOException - { - String l; - StringBuilder sb = new StringBuilder(); - - BufferedReader r = new BufferedReader(input); - while ((l = r.readLine()) != null) - { - sb.append(l); - if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) - sb.append("\n"); - } - r.close(); - return sb.toString(); - } - - /* Reflect */ - - /** - * @param cls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.2.2 - */ - public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(null, cls, name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(obj, obj.getClass(), name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param objCls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException - { - Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); - if (result != null) - return result; - result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); - if (result == null) - LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); - return result; - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param objCls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param argClasses | Classes of args. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException - { - try - { - Method method = objCls.getMethod(name, argClasses); - Object result = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : result; - } - catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) - { - for (Method method : objCls.getMethods()) - if (method.getName().equals(name)) - try - { - Object result = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : result; - } - catch (IllegalArgumentException e) - {} - catch (SecurityException | IllegalAccessException ex) - { - ex.printStackTrace(); - } - } - return null; - } - - - //Syntactical analyzes and fast string utility: - - /** - * @param obj | Object to clone. - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! - * - * @since 1.2.2 - */ - public static T Clone(T obj) - { - return Clone(obj, DataParser.REGISTRY, new Object[0], new Scope()); - } - - /** - * @param obj | Object to clone. - * @param parsersToUse | Parsers that will be used for cloning... - * @param converterArgs | Argument for {@link DataConverter#objToString(Object, Object...)}! - * @param parserArgs | Arguments for {@link ParserRegistry#parse(String, boolean, Class, Object...)}! - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! Also note that certain objects such as primitive wrappers ({@link Integer}, {@link Float} etc...) will not be necessarily cloned since cloning them is not reasonable... - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Clone(T obj, Collection parsersToUse, Object[] converterArgs, Object... parserArgs) - { - if (obj == null) - return null; - if (obj.getClass() == Byte.class) - return (T) (Byte) ((byte) obj); // valueOf call... - if (obj.getClass() == Short.class) - return (T) (Short) ((short) obj); - if (obj.getClass() == Integer.class) - return (T) (Integer) ((int) obj); - if (obj.getClass() == Long.class) - return (T) (Long) ((long) obj); - if (obj.getClass() == Float.class) - return (T) (Float) ((float) obj); - if (obj.getClass() == Double.class) - return (T) (Double) ((double) obj); - if (obj.getClass() == Character.class) - return (T) (Character) ((char) obj); - if (obj.getClass() == Boolean.class) - return (T) (Boolean) ((boolean) obj); - if (obj.getClass() == String.class) - return (T) new String((String) obj); - - ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); - - Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); - if (cln != null && cln != VOID) - return (T) cln; - - if (obj instanceof Cloneable) - { - try - { - Method method = Object.class.getDeclaredMethod("clone"); - method.setAccessible(true); - return (T) method.invoke(obj); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); - return obj; - } - - /** - * @param cls | Class to instantiate. - * - * @return New blank instance of required class created by calling shortest public constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.2.2 - */ - public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException - { - return Instantiate(cls, true); - } - - /** - * @param cls | Class to instantiate. - * @param publicOnly | If true, only public constructors will be used to create the object! - * - * @return New blank instance of required class created by calling shortest constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException - { - try - { - Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); - if (!publicOnly) - cons.setAccessible(true); - return cons.newInstance(); - } - catch (Exception e) - { - try - { - Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); - if (cnstrs.length <= 0) - throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); - - for (int i = 1; i < cnstrs.length; i++) - { - if (!publicOnly) - cnstrs[0].setAccessible(true); - if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) - cnstrs[0] = cnstrs[i]; - } - - Object[] args = new Object[cnstrs[0].getParameterCount()]; - Class[] argTypes = cnstrs[0].getParameterTypes(); - for (int i = 0; i < cnstrs[0].getParameterCount(); i++) - { - if (argTypes[i] == byte.class) - args[i] = (byte) 0; - else if (argTypes[i] == short.class) - args[i] = (short) 0; - else if (argTypes[i] == int.class) - args[i] = 0; - else if (argTypes[i] == long.class) - args[i] = 0l; - else if ( argTypes[i] == float.class) - args[i] = 0.0f; - else if (argTypes[i] == double.class) - args[i] = 0.0; - else if (argTypes[i] == char.class) - args[i] = (char) 0; - else if (argTypes[i] == boolean.class) - args[i] = false; - else if (argTypes[i] == String.class) - args[i] = ""; - else - args[i] = null; - } - return (T) cnstrs[0].newInstance(args); - } - catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) - { - e2.printStackTrace(); - } - } - return null; - } - - /** - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.2.2 - */ - public static Class[] ToClasses(Object... objs) - { - return ToClasses(true, objs); - } - - /** - * @param unwrap | If the box types should be unwrapped to primitives... - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.3.5 - */ - public static Class[] ToClasses(boolean unwrap, Object... objs) - { - Class[] classes = new Class[objs.length]; - if (unwrap) - { - for (int i = 0; i < classes.length; i++) - { - if (objs[i] == null) - classes[i] = Object.class; - else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) - classes[i] = byte.class; - else if (objs[i].getClass() == Short.class || objs[i] == Short.class) - classes[i] = short.class; - else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) - classes[i] = int.class; - else if (objs[i].getClass() == Long.class || objs[i] == Long.class) - classes[i] = long.class; - else if (objs[i].getClass() == Float.class || objs[i] == Float.class) - classes[i] = float.class; - else if (objs[i].getClass() == Double.class || objs[i] == Double.class) - classes[i] = double.class; - else if (objs[i].getClass() == Character.class || objs[i] == Character.class) - classes[i] = char.class; - else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) - classes[i] = boolean.class; - else if (objs[i] instanceof Class) - classes[i] = (Class) objs[i]; - else - classes[i] = objs[i].getClass(); - } - - return classes; - } - - for (int i = 0; i < classes.length; i++) - classes[i] = objs[i] == null ? Object.class : objs[i].getClass(); - return classes; - } - - /* Characters */ - - /** - * @param ch | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; - * - * @since 1.3.2 - */ - public static StringBuilder multilpy(char ch, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(ch); - return sb; - } - - /** - * @param str | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; - * - * @since 1.3.0 - */ - public static StringBuilder multilpy(CharSequence str, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(str); - return sb; - } - - /** - * @param s | String to split and check some syntax. - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} - * - * @since 1.0.0 - */ - public static String[] splitValues(String s, char... splitter) - { - return splitValues(s, 0, 2, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.0 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.5 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.8 - */ - public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - if (splitter.length <= 0 || limit == 1) - return new String[] {s}; -// -// if (isOneOf(s.charAt(0), splitter)) -// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); - - List result = new ArrayList<>(); - - int lastIndex = 0, len = s.length(); - for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) - { - int ch = s.charAt(i); - if (ch == '"') - { - do if (++i >= len) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); - while (s.charAt(i) != '"'); - } - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && s.charAt(i) != '"'); - } - } - else if (isOneOf(ch, splitBreaks)) - break; - else if (isOneOf(ch, splitter) && - (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) - { - String tok = s.substring(lastIndex, i).trim(); - if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) - { - result.add(tok); - lastIndex = i + 1; - - count++; - } - } - - oldCh = ch; - } - - result.add(s.substring(lastIndex, len).trim()); - return result.toArray(new String[0]); - } - - /** - * @param s | CharSequence to search! - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, char... oneOf) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be s.length()). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) - { - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else if (isOneOf(ch, oneOf)) - { - if (firstIndex) - return from; - defaultReturn = from; - } - } - return defaultReturn; - } - - /** - * @param s | CharSequence to search! - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be s.length()). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) - { - if (sequencesToFind.length < 1) - return defaultReturn; - - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else - { - findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) - { - CharSequence currentMatch; - if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) - { - int match = 1, lenToFind = currentMatch.length(); - for (int i = from+1; i < to && match < lenToFind; i++, match++) - if (s.charAt(i) != currentMatch.charAt(match)) - continue findMatch; - - if (match == lenToFind) - { - defaultReturn = from; - if (firstIndex) - return defaultReturn; - } - } - } - } - } - return defaultReturn; - } - - /** - * @param str | String to do replacements in! - * @param target | Target to replace! - * @param replacement | Replacement for target! - * - * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! - * - * @since 1.2.0 - */ - public static String fastReplace(String str, String target, CharSequence replacement) - { - int targetLength = target.length(); - if (targetLength == 0) - return str; - - int i1 = 0, i2 = str.indexOf(target); - if (i2 < 0) - return str; - - int len = str.length(); - StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); - do - { - sb.append(str, i1, i2).append(replacement); - i1 = i2 + targetLength; - i2 = str.indexOf(target, i1); - } while (i2 > 0); - - return sb.append(str, i1, len).toString(); - } - - /** - * @param ch | Char to compare! - * @param chars | Chars to match! - * - * @return True if inserted char (ch) is any of inserted chars! - * - * @since 1.3.0 - */ - public static boolean isOneOf(int ch, char... chars) - { - final int charsLen = chars.length; - for (int i = 0; i < charsLen; i++) - if (chars[i] == ch) - return true; - return false; - } - - /** - * @param str | Char sequence to search. - * @param oneOf | Chars to search for! - * - * @return {@link String#contains(CharSequence)} for char sequence! - * - * @since 1.3.0 - */ - public static boolean contains(CharSequence str, char... oneOf) - { - if (oneOf.length == 1) - { - for (int i = 0, len = str.length(); i < len; i++) - if (str.charAt(i) == oneOf[0]) - return true; - return false; - } - - for (int i = 0, len = str.length(); i < len; i++) - if (isOneOf(str.charAt(i), oneOf)) - return true; - return false; - } - - /** - * @param str | Source string to compare. - * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! - * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). - * @param to | The ending marking index, index where to end the comparing (exclusive, most likely str.length()) - * - * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
- * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
- * Also sufficient length of both strings is not checked so adjust from and to accordingly. - * - * @since 1.3.8 - */ - public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) - { - for (; from < to; from++) - if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) - return false; - return true; - } - - /** - * @param str | String to display! - * @param pos | Position to display! - * - * @return String with displayed position by using » or ^ under it! - * Use for debugging or error printing! - * - * @since 1.3.2 - */ - public static String showPosInString(CharSequence str, int pos) - { - if (pos < 0) - return str.toString(); - - try - { - if (contains(str, ENDL)) - return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); - return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); - } - catch (IndexOutOfBoundsException e) - { - return str.toString(); - } - } - - /* Arrays */ - - /** - * @param sourceArray | Array to cast! - * @param toType | Type to cast array in to! - * - * @return Array object casted in to required type! - * - * @since 1.3.2 - */ - public static Object castArray(Object[] sourceArray, Class toType) - { - int len; - Object arr = Array.newInstance(ToClasses(toType)[0], len = sourceArray.length); - for (int i = 0; i < len; i++) - Array.set(arr, i, sourceArray[i]); - return arr; - } - - /** - * @param arr1 | Object one that might be array! - * @param arr2 | Object two that might be array! - * - * @return New array consisting of array 1 and array 2! - * - * @throws IllegalArgumentException if object one is not an array! - * - * @since 1.3.2 - */ - public static Object[] mergeArrays(Object arr1, Object arr2) - { - Object[] array1 = fromAmbiguousArray(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguousArray(arr2) : new Object[] { arr2 }; - Object[] result = Arrays.copyOf(array1, array1.length + array2.length); - System.arraycopy(array2, 0, result, array1.length, array2.length); - return result; - } - - /** - * @param array | Object that might be array! - * - * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! - * - * @throws IllegalArgumentException if the specified object is not an array! - * - * @since 1.3.2 (since 1.3.8 moved from ArrayConverter) - */ - public static Object[] fromAmbiguousArray(Object array) - { - if (array instanceof Object[]) - return (Object[]) array; - - int len = Array.getLength(array); // Arr of primitives cos Java... - Object[] arr = new Object[len]; - for (int i = 0; i < len; i++) - arr[i] = Array.get(array, i); - return arr; - } - - /* Others... */ - - /** - * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! - * - * @param serializer | Serializer to post. - * @param conn | Http connection to use! - * - * @throws IOException if posting failed! - * - * @since 1.3.5 - */ - public static void post(Serializer serializer, HttpURLConnection conn) throws IOException - { - StringBuilder postData = new StringBuilder(); - for (Map.Entry param : serializer.varEntrySet()) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); - } - - for (Object param : serializer) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); - } - - byte[] postDataBytes = postData.toString().getBytes("UTF-8"); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); - conn.setDoOutput(true); - conn.getOutputStream().write(postDataBytes); - } +package org.ugp.serialx.utils; + +import static org.ugp.serialx.converters.DataParser.VOID; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.protocols.SerializationProtocol; + +/** + * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection. + * + * @author PETO + * + * @since 1.3.8 + */ +public final class Utils { + private Utils() {} + + /** + * {@link System#lineSeparator()} + * + * @since 1.3.9 + */ + public static final char[] ENDL = System.lineSeparator().toCharArray(); + + /** + * @param f | Source file. + * + * @return All lines from source file as string. + * @throws IOException + * + * @since 1.1.5 + */ + public static String LoadFileToString(File f) throws IOException + { + return LoadFileToString(f, 1); + } + + /** + * @param f | Source file. + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Content of file as string. + * @throws IOException + * + * @since 1.2.0 + */ + public static String LoadFileToString(File f, int endlMode) throws IOException + { + return StreamToString(new FileReader(f), endlMode); + } + + /** + * @param input | Input stream to read to string! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.5 + */ + public static String StreamToString(InputStream input, int endlMode) throws IOException + { + return StreamToString(new InputStreamReader(input), endlMode); + } + + /** + * @param input | Input reader! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.2 + */ + public static String StreamToString(Reader input, int endlMode) throws IOException + { + String l; + StringBuilder sb = new StringBuilder(); + + BufferedReader r = new BufferedReader(input); + while ((l = r.readLine()) != null) + { + sb.append(l); + if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) + sb.append("\n"); + } + r.close(); + return sb.toString(); + } + + /* Reflect */ + + /** + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.2.2 + */ + public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(null, cls, name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(obj, obj.getClass(), name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param objCls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException + { + Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); + if (result != null) + return result; + result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); + if (result == null) + LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); + return result; + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param objCls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param argClasses | Classes of args. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException + { + try + { + Method method = objCls.getMethod(name, argClasses); + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; + } + catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) + { + for (Method method : objCls.getMethods()) + if (method.getName().equals(name)) + try + { + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; + } + catch (IllegalArgumentException e) + {} + catch (SecurityException | IllegalAccessException ex) + { + ex.printStackTrace(); + } + } + return null; + } + + + //Syntactical analyzes and fast string utility: + + /** + * @param obj | Object to clone. + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.2.2 + */ + public static T Clone(T obj) + { + return Clone(obj, DataParser.REGISTRY, new Object[0], new Scope()); + } + + /** + * @param obj | Object to clone. + * @param parsersToUse | Parsers that will be used for cloning... + * @param converterArgs | Argument for {@link DataConverter#objToString(Object, Object...)}! + * @param parserArgs | Arguments for {@link ParserRegistry#parse(String, boolean, Class, Object...)}! + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! Also note that certain objects such as primitive wrappers ({@link Integer}, {@link Float} etc...) will not be necessarily cloned since cloning them is not reasonable... + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Clone(T obj, Collection parsersToUse, Object[] converterArgs, Object... parserArgs) + { + if (obj == null) + return null; + if (obj.getClass() == Byte.class) + return (T) (Byte) ((byte) obj); // valueOf call... + if (obj.getClass() == Short.class) + return (T) (Short) ((short) obj); + if (obj.getClass() == Integer.class) + return (T) (Integer) ((int) obj); + if (obj.getClass() == Long.class) + return (T) (Long) ((long) obj); + if (obj.getClass() == Float.class) + return (T) (Float) ((float) obj); + if (obj.getClass() == Double.class) + return (T) (Double) ((double) obj); + if (obj.getClass() == Character.class) + return (T) (Character) ((char) obj); + if (obj.getClass() == Boolean.class) + return (T) (Boolean) ((boolean) obj); + if (obj.getClass() == String.class) + return (T) new String((String) obj); + + ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); + + Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); + if (cln != null && cln != VOID) + return (T) cln; + + if (obj instanceof Cloneable) + { + try + { + Method method = Object.class.getDeclaredMethod("clone"); + method.setAccessible(true); + return (T) method.invoke(obj); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); + return obj; + } + + /** + * @param cls | Class to instantiate. + * + * @return New blank instance of required class created by calling shortest public constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.2.2 + */ + public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException + { + return Instantiate(cls, true); + } + + /** + * @param cls | Class to instantiate. + * @param publicOnly | If true, only public constructors will be used to create the object! + * + * @return New blank instance of required class created by calling shortest constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException + { + try + { + Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); + if (!publicOnly) + cons.setAccessible(true); + return cons.newInstance(); + } + catch (Exception e) + { + try + { + Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); + if (cnstrs.length <= 0) + throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); + + for (int i = 1; i < cnstrs.length; i++) + { + if (!publicOnly) + cnstrs[0].setAccessible(true); + if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) + cnstrs[0] = cnstrs[i]; + } + + Object[] args = new Object[cnstrs[0].getParameterCount()]; + Class[] argTypes = cnstrs[0].getParameterTypes(); + for (int i = 0; i < cnstrs[0].getParameterCount(); i++) + { + if (argTypes[i] == byte.class) + args[i] = (byte) 0; + else if (argTypes[i] == short.class) + args[i] = (short) 0; + else if (argTypes[i] == int.class) + args[i] = 0; + else if (argTypes[i] == long.class) + args[i] = 0l; + else if ( argTypes[i] == float.class) + args[i] = 0.0f; + else if (argTypes[i] == double.class) + args[i] = 0.0; + else if (argTypes[i] == char.class) + args[i] = (char) 0; + else if (argTypes[i] == boolean.class) + args[i] = false; + else if (argTypes[i] == String.class) + args[i] = ""; + else + args[i] = null; + } + return (T) cnstrs[0].newInstance(args); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) + { + e2.printStackTrace(); + } + } + return null; + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.2.2 + */ + public static Class[] ToClasses(Object... objs) + { + return ToClasses(true, objs); + } + + /** + * @param unwrap | If the box types should be unwrapped to primitives... + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.3.5 + */ + public static Class[] ToClasses(boolean unwrap, Object... objs) + { + Class[] classes = new Class[objs.length]; + if (unwrap) + { + for (int i = 0; i < classes.length; i++) + { + if (objs[i] == null) + classes[i] = Object.class; + else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) + classes[i] = byte.class; + else if (objs[i].getClass() == Short.class || objs[i] == Short.class) + classes[i] = short.class; + else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) + classes[i] = int.class; + else if (objs[i].getClass() == Long.class || objs[i] == Long.class) + classes[i] = long.class; + else if (objs[i].getClass() == Float.class || objs[i] == Float.class) + classes[i] = float.class; + else if (objs[i].getClass() == Double.class || objs[i] == Double.class) + classes[i] = double.class; + else if (objs[i].getClass() == Character.class || objs[i] == Character.class) + classes[i] = char.class; + else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) + classes[i] = boolean.class; + else if (objs[i] instanceof Class) + classes[i] = (Class) objs[i]; + else + classes[i] = objs[i].getClass(); + } + + return classes; + } + + for (int i = 0; i < classes.length; i++) + classes[i] = objs[i] == null ? Object.class : objs[i].getClass(); + return classes; + } + + /* Characters */ + + /** + * @param ch | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; + * + * @since 1.3.2 + */ + public static StringBuilder multilpy(char ch, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(ch); + return sb; + } + + /** + * @param str | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; + * + * @since 1.3.0 + */ + public static StringBuilder multilpy(CharSequence str, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(str); + return sb; + } + + /** + * @param s | String to split and check some syntax. + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} + * + * @since 1.0.0 + */ + public static String[] splitValues(String s, char... splitter) + { + return splitValues(s, 0, 2, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.0 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.5 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.8 + */ + public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + if (splitter.length <= 0 || limit == 1) + return new String[] {s}; +// +// if (isOneOf(s.charAt(0), splitter)) +// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); + + List result = new ArrayList<>(); + + int lastIndex = 0, len = s.length(); + for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) + { + int ch = s.charAt(i); + if (ch == '"') + { + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + while (s.charAt(i) != '"'); + } + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + } + } + else if (isOneOf(ch, splitBreaks)) + break; + else if (isOneOf(ch, splitter) && + (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + String tok = s.substring(lastIndex, i).trim(); + if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) + { + result.add(tok); + lastIndex = i + 1; + + count++; + } + } + + oldCh = ch; + } + + result.add(s.substring(lastIndex, len).trim()); + return result.toArray(new String[0]); + } + + /** + * @param s | CharSequence to search! + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, char... oneOf) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) + { + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else if (isOneOf(ch, oneOf)) + { + if (firstIndex) + return from; + defaultReturn = from; + } + } + return defaultReturn; + } + + /** + * @param s | CharSequence to search! + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) + { + if (sequencesToFind.length < 1) + return defaultReturn; + + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else + { + findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) + { + CharSequence currentMatch; + if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) + { + int match = 1, lenToFind = currentMatch.length(); + for (int i = from+1; i < to && match < lenToFind; i++, match++) + if (s.charAt(i) != currentMatch.charAt(match)) + continue findMatch; + + if (match == lenToFind) + { + defaultReturn = from; + if (firstIndex) + return defaultReturn; + } + } + } + } + } + return defaultReturn; + } + + /** + * @param str | String to do replacements in! + * @param target | Target to replace! + * @param replacement | Replacement for target! + * + * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! + * + * @since 1.2.0 + */ + public static String fastReplace(String str, String target, CharSequence replacement) + { + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + int len = str.length(); + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, len).toString(); + } + + /** + * @param ch | Char to compare! + * @param chars | Chars to match! + * + * @return True if inserted char (ch) is any of inserted chars! + * + * @since 1.3.0 + */ + public static boolean isOneOf(int ch, char... chars) + { + final int charsLen = chars.length; + for (int i = 0; i < charsLen; i++) + if (chars[i] == ch) + return true; + return false; + } + + /** + * @param str | Char sequence to search. + * @param oneOf | Chars to search for! + * + * @return {@link String#contains(CharSequence)} for char sequence! + * + * @since 1.3.0 + */ + public static boolean contains(CharSequence str, char... oneOf) + { + if (oneOf.length == 1) + { + for (int i = 0, len = str.length(); i < len; i++) + if (str.charAt(i) == oneOf[0]) + return true; + return false; + } + + for (int i = 0, len = str.length(); i < len; i++) + if (isOneOf(str.charAt(i), oneOf)) + return true; + return false; + } + + /** + * @param str | Source string to compare. + * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! + * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). + * @param to | The ending marking index, index where to end the comparing (exclusive, most likely {@code >= to <= str.length()}) + * + * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
+ * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
+ * Also sufficient length of both strings is not checked so adjust from and to accordingly. + * + * @since 1.3.8 + */ + public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) + { + for (; from < to; from++) + if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) + return false; + return true; + } + + /** + * @param str | String to display! + * @param pos | Position to display! + * + * @return String with displayed position by using » or ^ under it! + * Use for debugging or error printing! + * + * @since 1.3.2 + */ + public static String showPosInString(CharSequence str, int pos) + { + if (pos < 0) + return str.toString(); + + try + { + if (contains(str, ENDL)) + return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); + return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); + } + catch (IndexOutOfBoundsException e) + { + return str.toString(); + } + } + + /* Arrays */ + + /** + * @param sourceArray | Array to cast! + * @param toType | Type to cast array in to! + * + * @return Array object casted in to required type! + * + * @since 1.3.2 + */ + public static Object castArray(Object[] sourceArray, Class toType) + { + int len; + Object arr = Array.newInstance(ToClasses(toType)[0], len = sourceArray.length); + for (int i = 0; i < len; i++) + Array.set(arr, i, sourceArray[i]); + return arr; + } + + /** + * @param arr1 | Object one that might be array! + * @param arr2 | Object two that might be array! + * + * @return New array consisting of array 1 and array 2! + * + * @throws IllegalArgumentException if object one is not an array! + * + * @since 1.3.2 + */ + public static Object[] mergeArrays(Object arr1, Object arr2) + { + Object[] array1 = fromAmbiguousArray(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguousArray(arr2) : new Object[] { arr2 }; + Object[] result = Arrays.copyOf(array1, array1.length + array2.length); + System.arraycopy(array2, 0, result, array1.length, array2.length); + return result; + } + + /** + * @param array | Object that might be array! + * + * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! + * + * @throws IllegalArgumentException if the specified object is not an array! + * + * @since 1.3.2 (since 1.3.8 moved from ArrayConverter) + */ + public static Object[] fromAmbiguousArray(Object array) + { + if (array instanceof Object[]) + return (Object[]) array; + + int len = Array.getLength(array); // Arr of primitives cos Java... + Object[] arr = new Object[len]; + for (int i = 0; i < len; i++) + arr[i] = Array.get(array, i); + return arr; + } + + /* Others... */ + + /** + * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! + * + * @param serializer | Serializer to post. + * @param conn | Http connection to use! + * + * @throws IOException if posting failed! + * + * @since 1.3.5 + */ + public static void post(Serializer serializer, HttpURLConnection conn) throws IOException + { + StringBuilder postData = new StringBuilder(); + for (Map.Entry param : serializer.varEntrySet()) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); + } + + for (Object param : serializer) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); + } + + byte[] postDataBytes = postData.toString().getBytes("UTF-8"); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); + conn.setDoOutput(true); + conn.getOutputStream().write(postDataBytes); + } } \ No newline at end of file From 004dfa14abe858b98bacd7484f3a40d8726e89c0 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Sun, 27 Sep 2026 20:17:23 +0200 Subject: [PATCH 70/75] Global crlf->lf --- .gitignore | 82 +- README.md | 4 +- SerialX-core/pom.xml | 32 +- .../java/org/ugp/serialx/GenericScope.java | 2225 ++++++++--------- .../org/ugp/serialx/MultimediaSerializer.java | 432 ++-- .../main/java/org/ugp/serialx/Serializer.java | 1472 +++++------ .../serialx/converters/BooleanConverter.java | 234 +- .../converters/CharacterConverter.java | 138 +- .../ugp/serialx/converters/DataConverter.java | 188 +- .../ugp/serialx/converters/DataParser.java | 818 +++--- .../ugp/serialx/converters/NullConverter.java | 132 +- .../serialx/converters/NumberConverter.java | 490 ++-- .../serialx/converters/ProtocolConverter.java | 924 +++---- .../SerializableBase64Converter.java | 272 +- .../serialx/converters/StringConverter.java | 332 +-- .../serialx/converters/VariableParser.java | 226 +- .../serialx/converters/imports/Import.java | 294 +-- .../converters/imports/ImportsProvider.java | 692 ++--- .../ugp/serialx/protocols/EnumProtocol.java | 62 +- .../ugp/serialx/protocols/ListProtocol.java | 88 +- .../ugp/serialx/protocols/MapProtocol.java | 114 +- .../ugp/serialx/protocols/ScopeProtocol.java | 94 +- .../protocols/SerializationProtocol.java | 910 +++---- .../ugp/serialx/protocols/StringProtocol.java | 124 +- .../org/ugp/serialx/utils/LogProvider.java | 150 +- .../java/org/ugp/serialx/utils/Registry.java | 842 +++---- .../java/org/ugp/serialx/utils/Utils.java | 1880 +++++++------- SerialX-devtools/pom.xml | 48 +- .../serialx/devtools/DebugParserRegistry.java | 358 +-- .../devtools/SerializationDebugger.java | 574 ++--- SerialX-json/pom.xml | 48 +- .../org/ugp/serialx/json/JsonSerializer.java | 806 +++--- .../converters/JsonCharacterConverter.java | 110 +- .../json/converters/JsonNumberConverter.java | 46 +- .../json/converters/JsonObjectConverter.java | 120 +- .../converters/JsonVariableConverter.java | 62 +- SerialX-juss/pom.xml | 48 +- .../org/ugp/serialx/juss/JussSerializer.java | 2056 +++++++-------- .../juss/converters/ArrayConverter.java | 360 +-- .../juss/converters/ImportConverter.java | 160 +- .../juss/converters/ObjectConverter.java | 384 +-- .../juss/converters/OperationGroups.java | 380 +-- .../juss/converters/VariableConverter.java | 536 ++-- .../serialx/juss/protocols/AutoProtocol.java | 430 ++-- .../juss/protocols/SelfSerializable.java | 40 +- .../protocols/SelfSerializableProtocol.java | 76 +- .../UniversalObjectInstantiationProtocol.java | 198 +- SerialX-operators/pom.xml | 48 +- .../org/ugp/serialx/converters/Operators.java | 138 +- .../operators/ArithmeticOperators.java | 1022 ++++---- .../operators/ComparisonOperators.java | 370 +-- .../ConditionalAssignmentOperators.java | 282 +-- .../operators/LogicalOperators.java | 264 +- .../operators/NegationOperator.java | 188 +- pom.xml | 302 +-- 55 files changed, 11352 insertions(+), 11353 deletions(-) diff --git a/.gitignore b/.gitignore index e2e18c1..61cd3e6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,41 +1,41 @@ -# Specifies intentionally untracked files to ignore when using Git -# http://git-scm.com/docs/gitignore - -*~ -*.sw[mnpcod] -.tmp -*.tmp -*.tmp.* -*.sublime-project -*.sublime-workspace -.DS_Store -Thumbs.db -UserInterfaceState.xcuserstate -$RECYCLE.BIN/ - -.flattened-* -*.log -log.txt -npm-debug.log* - -/.idea -/.ionic -/.sass-cache -/.sourcemaps -/.versions -/.vscode -/coverage -/dist -/node_modules -/platforms -/plugins -/www - -bin/ -tmp/ -.metadata -.classpath -.settings -.project - -target/ +# Specifies intentionally untracked files to ignore when using Git +# http://git-scm.com/docs/gitignore + +*~ +*.sw[mnpcod] +.tmp +*.tmp +*.tmp.* +*.sublime-project +*.sublime-workspace +.DS_Store +Thumbs.db +UserInterfaceState.xcuserstate +$RECYCLE.BIN/ + +.flattened-* +*.log +log.txt +npm-debug.log* + +/.idea +/.ionic +/.sass-cache +/.sourcemaps +/.versions +/.vscode +/coverage +/dist +/node_modules +/platforms +/plugins +/www + +bin/ +tmp/ +.metadata +.classpath +.settings +.project + +target/ diff --git a/README.md b/README.md index 918a497..0e089e7 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ -# Java-SerialX dev -This the main development branch! +# Java-SerialX dev +This the main development branch! diff --git a/SerialX-core/pom.xml b/SerialX-core/pom.xml index 8d4a47d..caa7266 100644 --- a/SerialX-core/pom.xml +++ b/SerialX-core/pom.xml @@ -1,17 +1,17 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-core - 4.0.0-SNAPSHOT - - SerialX core - Core of SerialX. Contains core features and utilities shared across the library. + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-core + 4.0.0-SNAPSHOT + + SerialX core + Core of SerialX. Contains core features and utilities shared across the library. \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 0a752e7..57c8d41 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -1,1113 +1,1112 @@ -package org.ugp.serialx; - -import static org.ugp.serialx.utils.Utils.Instantiate; - -import java.io.Serializable; -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Objects; -import java.util.Set; -import java.util.function.Function; -import java.util.function.Predicate; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; - - -/** - * This collection is some sort of hybrid, or more accurately "union" between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
- * Note: Variables are managed and accessed classically via {@link Map} methods such as put(KeyT key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
- * Also this is java representation of JUSS GenericScope group such as: - *
- * 
- * {
- *     //This is generic scope in JUSS! Variable keys are generic!
- * }
- * 
- * 
- * - * @author PETO - * - * @since 1.3.5 - * - * @param generic type of variables key. - * @param generic type of variables value and independent value. - */ -public class GenericScope implements Collection, Cloneable, Serializable -{ - private static final long serialVersionUID = 5717775602991055386L; - - protected Map variables; - protected List values; - protected GenericScope parent; - - /** - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.2.0 - */ - @SafeVarargs - public GenericScope(ValT... values) - { - this(null, values); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.2.0 - */ - @SafeVarargs - public GenericScope(Map variablesMap, ValT... values) - { - this(variablesMap, values == null ? null : Arrays.asList(values), null); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.2.0 - */ - public GenericScope(Map variablesMap, Collection values) - { - this(variablesMap, values, null); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * @param parent | Parent of this scope. - - * @since 1.2.0 - */ - public GenericScope(Map variablesMap, Collection values, GenericScope parent) - { - if (variablesMap != null) - this.variables = new LinkedHashMap<>(variablesMap); - if (values != null) - this.values = new ArrayList<>(values); - this.parent = parent; - } - - @Override - public boolean equals(Object obj) - { - if (obj instanceof GenericScope) - return values().equals(((GenericScope) obj).values()) && variables().equals(((GenericScope) obj).variables()); - if (obj instanceof Collection) - return variablesCount() <= 0 && values().equals(obj); - if (obj instanceof Map) - return valuesCount() <= 0 && variables().equals(obj); - if (obj != null && obj.getClass().isArray()) - return variablesCount() <= 0 && Objects.deepEquals(toArray(), Utils.fromAmbiguousArray(obj)); - return super.equals(obj); - } - - @Override - public String toString() - { - String name = getClass().getSimpleName(); - final int varCount; - if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0) - return name + (varCount > 0 ? variables() : values()); - return name + toUnifiedList(); - } - - @Override - public int hashCode() - { - final int varCount; - if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0) - return (varCount > 0 ? variables() : values()).hashCode(); - return Objects.hash(variables(), values()); - } - - @SuppressWarnings("unchecked") - @Override - public GenericScope clone() - { - try - { - return clone(getClass()); - } - catch (Exception e) - { - return new GenericScope<>(variables(), values(), getParent()); - } - } - - /** - * @param typeOfClone | Class representing type of scope that will be created. - * @return Copy of this scope converted to instance of typeOfClone. - * - * @throws Exception | When program was unable to create instance of typeOfClone. - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public > S clone(Class typeOfClone) throws Exception - { - S clone = Instantiate(typeOfClone); - clone.values = (List) toValList(); - clone.variables = (Map) toVarMap(); - clone.parent = getParent(); - return (S) clone; - } - - /** - * @param newType | Type of new scope. - * @return Original scope retyped/casted into instance of newType. Similar to {@link GenericScope#clone(Class)} but this will share same instances of values list and variables map with original! - * - * @throws Exception | When program was unable to create instance of newType. - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public > S castTo(Class newType) throws Exception - { - if (getClass() == newType) - return (S) this; - - GenericScope clone = (GenericScope) Instantiate(newType); - clone.values = (List) values(); - clone.variables = (Map) variables(); - clone.parent = getParent(); - return (S) clone; - } - - /** - * @return Iterator of independent values. - * - * @since 1.2.0 - */ - @Override - public Iterator iterator() - { - return values().iterator(); - } - - /** - * Insert new variable. - * - * @param variableKey | Name of variable. - * @param variableValue | Variables value. - * - * @return Old value of variable with given name or null is there was no this variable before! - * - * @since 1.2.0 - */ - public ValT put(KeyT variableKey, ValT variableValue) - { - if (variableValue instanceof GenericScope && ((GenericScope) variableValue).getParent() == null) - ((GenericScope) variableValue).parent = this; - return variables().put(variableKey, variableValue); - } - - /** - * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... - * - * @return Array of values previously at keys from kv array. - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public ValT[] putAllKv(Object... kVkVkV) - { - ValT[] oldValues = (ValT[]) new Object[kVkVkV.length/2]; - for (int i = 1; i < kVkVkV.length; i+=2) { - oldValues[i/2] = put((KeyT) kVkVkV[i-1], (ValT) kVkVkV[i]); - } - return oldValues; - } - - /** - * @param index | Index of variable! - * - * @return Value of variable at required index or null if index was not found! - * - * @since 1.2.5 - */ - public V getVarAt(int index) - { - return getVarAt(index, null); - } - - /** - * @param index | Index of variable! - * @param defaultValue | Default value to return. - * - * @return Value of variable at required index or defaultValue if index was not found! - * - * @since 1.2.5 - */ - @SuppressWarnings("unchecked") - public V getVarAt(int index, V defaultValue) - { - int i = 0; - for (Map.Entry ent : varEntrySet()) - if (i++ == index) - return (V) ent.getValue(); - return defaultValue; - } - - /** - * @param variableKey | Variables name. - * - * @return Value of variable with name or null if there is no such a one! - * - * @since 1.2.0 - */ - public V get(KeyT variableKey) - { - return get(variableKey, null); - } - - /** - * @param variableKey | Variables name. - * @param defaultValue | Default value to return. - * - * @return Value of variable with name or defaultValue if there is no such a one (or given key contains null)! - * - * @since 1.2.5 - */ - @SuppressWarnings("unchecked") - public V get(KeyT variableKey, V defaultValue) - { - V obj; - if ((obj = (V) variables().get(variableKey)) == null) - return defaultValue; - return obj; - } - - /** - * @param pathToValue | Array with variables creating path to required value, nested in multiple sub-scopes. - * - * @return Value of variable at given path. If no path is given (length is 0) then this {@link GenericScope} will be returned.
- * If 1 path argument is given then this behaves similarly to {@link GenericScope#get(Object)}.
- * if 2+ path arguments are given then it will search the sub-scopes and return first match value. For example:
- * In either way, if there is no suitable result then null will be returned!
- * Consider this scope tree:
- *
-	 * 
-	 * {
-	 *   125: {
-	 *   	"hello": {
-	 *   		"value" true
-	 *   	}
-	 *   }
-	 * }
-	 * 
-	 * 
- * Then to get value of "value" you can do scope.get(125, "hello", "value")!
- * If there is no other variable called "value" in the scope tree then you can also simplify it to scope.get("value"), but make sure that there is no equally-named variable!
- * Note: Make sure that you are not calling {@link GenericScope#get(Object, Object)} by accident when you are using inline vargas array (unspecified count of arguments)! - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public V get(KeyT... pathToValue) - { - try - { - if (pathToValue.length <= 0) - return (V) this; - Object obj = get((KeyT) pathToValue[0]); - if (obj instanceof GenericScope) - return ((GenericScope) obj).get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); - for (Map.Entry var : varEntrySet()) - if (var.getValue() instanceof GenericScope) - try - { - GenericScope sc = (GenericScope) var.getValue(); - if ((sc = sc.getGenericScope(pathToValue[0])) != null) - return sc.get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); - } - catch (Exception e) {} - - return (V) obj; - } - catch (ClassCastException e) - {} - return null; - } - - /** - * @param variableKey | Variables name. - * @param cls | Default value to return. - * @param defaultValue | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. - * - * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one (or given key contains null)! - * - * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)} - * - * @since 1.3.8 - */ - public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception - { - V obj = get(variableKey, defaultValue); - if (obj != null && obj.getClass() == cls) - return obj; - if (obj instanceof GenericScope) - return ((GenericScope) obj).toObject(cls); - return obj; - } - - /** - * @param variableKey | Variables name to search for. - * - * @return True if variable with given name was found in this scope. - * - * @since 1.2.0 - */ - public boolean containsVariable(KeyT variableKey) - { - return variables().containsKey(variableKey); - } - - /** - * @param value | Object the independent value. - * - * @return True if independent value was found in this scope. - * - * @since 1.3.8 - */ - @Override - public boolean contains(Object value) - { - return values().contains(value); - } - - /** - * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! - * {@link IndexOutOfBoundsException} will be thrown if index is too big! - * - * @return Independent value with valueIndex of this {@link GenericScope}! - * - * @since 1.2.0 - */ - @SuppressWarnings("unchecked") - public V get(int valueIndex) - { - return (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); - } - - /** - * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! - * @param cls | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. - * - * @return Independent value with valueIndex of this converted to object of cls! - * - * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! - * - * @since 1.3.8 - */ - public V get(int valueIndex, Class cls) throws Exception - { - V obj = get(valueIndex); - if (obj != null && obj.getClass() == cls) - return obj; - if (obj instanceof GenericScope) - return ((GenericScope) obj).toObject(cls); - return obj; - } - - /** - * @param value | Independent value to add into array of values. - * - * @return {@link ArrayList#add(Object)} - * - * @since 1.2.0 - */ - @Override - public boolean add(ValT value) - { - boolean result = values().add(value); - if (result && value instanceof GenericScope && ((GenericScope) value).getParent() == null) - ((GenericScope) value).parent = this; - return result; - } - - /** - * @param values | List of independent value or values to add into array of values. - * - * @return {@link ArrayList#add(Object)} - * - * @since 1.2.0 - */ - @Override - public boolean addAll(Collection values) - { - if (values.isEmpty()) - return false; - return values().addAll((Collection) values); - } - - /** - * @param values | Array of independent value or values to add into array of values. - * - * @return {@link GenericScope#addAll(Object...)} - * - * @since 1.3.2 - */ - public boolean addAll(@SuppressWarnings("unchecked") ValT... values) - { - return addAll(Arrays.asList(values)); - } - - /** - * @param variables | Map of variables to put in. (Will use {@link Map#putAll(Map)}) - * - * @return This generic scope after the variables were added into it. - * - * @since 4.0.0 - */ - public GenericScope putAll(Map variables) - { - if (variables.isEmpty()) - return this; - variables().putAll(variables); - return this; - } - - /** - * @param values | Independent values to check. - * - * @return True all provided values are contained in this scope as independent values! - * - * @since 1.3.8 - */ - @Override - public boolean containsAll(Collection values) - { - return values().containsAll(values); - } - - /** - * @param values | Independent values to check. - * - * @return {@link Collection#removeAll(Collection)} for the independent values,,, - * - * @since 1.3.8 - */ - @Override - public boolean removeAll(Collection values) - { - return values().removeAll(values); - } - - /** - * @param values | Independent values to check. - * - * @return {@link Collection#retainAll(Collection)} for the independent values,,, - * - * @since 1.3.8 - */ - @Override - public boolean retainAll(Collection values) - { - return values().retainAll(values); - } - - /** - * @param scopeValueIndex | Index of sub-scopes value. - * - * @return Sub-scope on required index or null if there is no scope on required index!
- * Note: Keep in mind that you need to insert valid index according to other values. Scopes share same index order with other values! - * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) - * - * @since 1.2.0 - */ - @SuppressWarnings("unchecked") - public GenericScope getGenericScope(int scopeValueIndex) - { - GenericScope obj = (GenericScope) get(scopeValueIndex); - if (obj instanceof GenericScope) - return (GenericScope) obj; - return null; - } - - /** - * @param pathToScope | Array with variables creating path to required scope. - * - * @return Sub-scope stored by variable with required name (last element of pathToScope) or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! - * This search will also includes sub-scopes stored by variables of this scope while variables from lower ones are prioritize!
- * If this function is called with no arguments then self will be returned! - * Note: Remember that this search includes variables only, no values!
- * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) - * - * @since 1.2.0 - */ - @SuppressWarnings("unchecked") - public GenericScope getGenericScope(K... pathToScope) - { - Object obj = get((KeyT[]) pathToScope); - if (obj instanceof GenericScope) - return (GenericScope) obj; - - if (containsVariable((KeyT) pathToScope[0])) - LogProvider.instance.logErr("Variable with name \"" + pathToScope[0] + "\" does exists! However its value is not instance of scope, use \"get\" function instead if possible!", null); - return null; - } - - /** - * @param type | Class of object to create (may or may not support other implementations of {@link Type}). - * - * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in {@link SerializationProtocol#REGISTRY}! - * - * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! - * - * @since 1.2.5 - */ - public T toObject(Type type) throws Exception - { - return toObject(type, SerializationProtocol.REGISTRY); - } - - /** - * @param type | Class of object to create using protocols (may or may not support other implementations of {@link Type}). - * @param protocolsToUse | Registry of protocols to use. - * - * @return Object of class constructed from this scopes independent values using protocol for given class or null if there was no protocol found in protocolsToUse! - * - * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public T toObject(Type type, ProtocolRegistry protocolsToUse) throws Exception - { - if (protocolsToUse == null) - return null; - - Class objClass; - SerializationProtocol pro; - if ((pro = protocolsToUse.GetProtocolFor(objClass = (Class) type, SerializationProtocol.MODE_DESERIALIZE)) != null) - { - T obj; - if ((obj = pro.unserialize(objClass, variablesCount() > 0 ? new Object[] {this} : toArray())) != null) - return obj; - } - return null; - } - - /** - * @param predicate | Predicate object with filter condition in test method! - * - * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! - * - * @since 1.2.5 - */ - public GenericScope filter(Predicate predicate) - { - return filter(predicate, false); - } - - /** - * @param predicate | Predicate object with filter condition in test method! - * @param includeSubScopes | If true filtration will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Predicate#test(Object)}). - * If sub-scope is empty after filtration it will not be included in result! - * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! - * - * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! - * - * @since 1.2.5 - */ - @SuppressWarnings("unchecked") - public GenericScope filter(Predicate predicate, boolean includeSubScopes) - { - return (GenericScope) transform(new Function() - { - @Override - public Object apply(ValT t) - { - return predicate.test(t) ? t : DataParser.VOID; - } - }, includeSubScopes); - } - - /** - * @param trans | Function to transform objects of this scope! - * - * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! - * - * @since 1.2.5 - */ - public GenericScope transform(Function trans) - { - return transform(trans, false); - } - - /** - * @param trans | Function to transform objects of this scope! - * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). - * If sub-scope is empty after transformation it will not be included in result! - * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! - * - * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! - * - * @since 1.2.5 - */ - @SuppressWarnings("unchecked") - public GenericScope transform(Function trans, boolean includeSubScopes) - { - if (trans == null || isEmpty()) - return (GenericScope) this; - - LinkedHashMap mappedVars = new LinkedHashMap<>(); - for (Entry ent : this.varEntrySet()) - try - { - Object obj = ent.getValue(); - if (includeSubScopes && obj instanceof GenericScope) - { - GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); - if (!sc.isEmpty()) - mappedVars.put(ent.getKey(), (V) sc); - } - else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) - mappedVars.put(ent.getKey(), trans.apply((ValT) obj)); - } - catch (ClassCastException e) - {} - - List mappedVals = map(trans, includeSubScopes); - try - { - GenericScope clone = Instantiate(getClass()); - clone.values = mappedVals; - clone.variables = mappedVars; - clone.parent = getParent(); - return clone; - } - catch (Exception e) - { - return new GenericScope<>(mappedVars, mappedVals, getParent()); - } - } - - /** - * @param trans | Function to transform independent objects of this scope! - * - * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! - * - * @since 1.3.5 - */ - public List map(Function trans) - { - return map(trans, false); - } - - /** - * @param trans | Function to transform independent objects of this scope! - * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). - * If sub-scope is empty after transformation it will not be included in result! - * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! - * - * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public List map(Function trans, boolean includeSubScopes) - { -// List mapped = new ArrayList<>(size()); -// for (Object obj : this) -// try -// { -// if (obj instanceof GenericScope && includeSubScopes) -// { -// GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); -// if (!sc.isEmpty()) -// mapped.add((V) sc); -// } -// else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) -// mapped.add((V) obj); -// } -// catch (ClassCastException e) -// {} - - List mapped = (List) toValList(); - for (int i = valuesCount()-1; i >= 0; i--) - { - try - { - Object obj = mapped.get(i); - if (includeSubScopes && obj instanceof GenericScope) - { - GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); - if (!sc.isEmpty()) - { - mapped.set(i, (V) sc); - continue; - } - } - else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) - { - mapped.set(i, (V) obj); - continue; - } - } - catch (ClassCastException e) - {} - - mapped.remove(i); - } - - return mapped; - } - - /** - * @param valueIndex | Index of independent value to remove! - * - * @return Removed independent value! - * - * @since 1.3.2 - */ - public ValT remove(int valueIndex) - { - return values().remove(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); - } - - /** - * @param independentValue | Independent value to remove! - * - * @return Value of variable that was removed! - * - * @since 1.3.8 - */ - @Override - public boolean remove(Object independentValue) - { - return values().remove(independentValue); - } - - /** - * @param variableKey | Name of variable to remove! - * - * @return Value of variable that was removed! - * - * @since 1.3.8 - */ - public ValT removeVariable(KeyT variableKey) - { - return variables().remove(variableKey); - } - - /** - * Removes all independent values and variables of this scope! - *
- * Basically it just calls variables().clear() and values().clear()! - * - * @since 1.3.5 - */ - @Override - public void clear() - { - if (variables != null) - variables.clear(); - if (values != null) - values.clear(); - } - - /** - * @return This scope after inheriting variables of its parent (return this)! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public GenericScope inheritParent() - { - GenericScope parent = getParent(); - if (parent != null) - variables().putAll((Map) parent.variables()); - return this; - } - - /** - * @param scope | GenericScope whose content will be added! - * - * @return This scope... - * - * @since 1.3.0 - */ - public GenericScope addAll(GenericScope scope) - { - values().addAll(scope.values()); - variables().putAll(scope.variables()); - return this; - } - - /** - * @return Entry set of variables! - * - * @since 1.2.0 - */ - public Set> varEntrySet() - { - return variables().entrySet(); - } - - /** - * @return Count of keyless values of this scope! (values().size()) - * - * @since 1.2.0 - */ - public int valuesCount() - { - return values().size(); - } - - /** - * @return Count of variables! (variables().size()) - * - * @since 1.2.0 - */ - public int variablesCount() - { - return variables().size(); - } - - /** - * @return Total number of variables and independent values of this scope! (vvaluesCount() + variablesCount()) - * - * @since 1.3.8 (before 1.3.8 known as totalSize) - */ - @Override - public int size() - { - return valuesCount() + variablesCount(); - } - - /** - * @return True if this scope is completely empty, meaning there are no variables or values. - * - * @since 1.2.0 - */ - @Override - public boolean isEmpty() - { - return size() <= 0; - } - - /** - * @return The parent scope of this scope or null if this scope has no parent such as default one in file.
- * Note: This may or may not be always null based on the way this scope was instantiated... - * - * @since 1.2.0 - */ - public > T getParent() - { - return getParent(1); - } - - /** - * @param depth | Positive number representing how many times will this method call itself...
For example 0 or less = this, 1 = parent, 2 = parentOfParent (parent.getParent()) and so on... - * If you want to get the root parent (the one that has no parent), simply put a big number as depth. 99 should be enough! - * - * @return The parent scope based on depth or null if this scope has no parent which means its already root (default one in file). - * If depth was bigger than 1, null will not be returned, last not null parent will be returned instead!
- * Note: This may or may not be always null based on the way this scope was instantiated... - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public > T getParent(int depth) - { - if (depth < 1) - return (T) this; - - GenericScope parentsParent; - if (depth == 1 || parent == null || (parentsParent = parent.getParent(--depth)) == null) - return (T) parent; - return (T) parentsParent; - } - - /** - * @return New {@link LinkedHashMap} with variables of this a in defined order! Key is a KeyT of variable and value is its value!
- * Modifying this map will not affect this GenericScope object! - * - * @since 1.2.0 - */ - public LinkedHashMap toVarMap() - { - return new LinkedHashMap<>(variables()); - } - - /** - * @return New {@link ArrayList} with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! - * Modifying this list will not affect this GenericScope object!
- * Note: Returning other {@link List} implementations than {@link ArrayList} (or other collection that stores elements in "array-like fashion") may result in serious performance implications! Queues or LinkedLists are the prime examples to avoid! - * - * @since 1.2.0 - */ - public List toValList() - { - return new ArrayList<>(values()); - } - - /** - * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! - * Modifying this list will not affect this {@link GenericScope} object! - * - * @since 1.3.8 (before 1.3.8 known as toValArray) - */ - @Override - public Object[] toArray() - { - return values().toArray(); - } - - /** - * @param vals | Array to store independent values into! - * - * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! - * Modifying this list will not affect this {@link GenericScope} object! - * - * @since 1.3.8 (before 1.3.8 known as toValArray) - */ - @Override - public T[] toArray(T[] vals) - { - return values().toArray(vals); - } - - /** - * @return List with both variables and values! Variables will be added as {@link Entry}! - * Variables will be always first! - * Modifying this map will not affect this GenericScope object! - * - * @since 1.3.0 - */ - @SuppressWarnings("unchecked") - public List toUnifiedList() - { - List list = (List) toValList(); - list.addAll(0, varEntrySet()); - return list; - } - - /** - * @return Independent values of this scope. These are not the values of keys these are values that have no key. You can access them via {@link GenericScope#get(int)}! - * Note: Editing this List will affect this scope! - * - * @since 1.2.0 - */ - public List values() - { - if (values == null) - values = new ArrayList<>(); - return values; - } - - /** - * @return Variables of this scope. Objecthis variables has nothing to do with values. Key is a KeyT name of variable and value is value of variable. - * Note: Editing this Map will affect this scope! - * - * @since 1.2.0 - */ - public Map variables() - { - if (variables == null) - variables = new LinkedHashMap<>(); - return variables; - } - - /** - * @param variablesMap | Variables map to use! - * - * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! - * - * @since 1.3.5 - */ - public static GenericScope newBidirectional(Map variablesMap) - { - return newBidirectional(variablesMap, null); - } - - /** - * @param variablesMap | Variables map to use! - * @param values | Values list to use! - * - * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! - * - * @since 1.3.5 - */ - public static GenericScope newBidirectional(Map variablesMap, List values) - { - return newBidirectional(variablesMap, values, null); - } - - /** - * @param variablesMap | Variables map to use! - * @param values | Values list to use! - * @param parent | Parent of scope! - * - * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! - * - * @since 1.3.5 - */ - public static GenericScope newBidirectional(Map variablesMap, List values, GenericScope parent) - { - return intoBidirectional(new GenericScope<>(null, null, null), variablesMap, values, parent); - } - - /** - * @param scopeToMakeBidirectional | GenericScope to make bidirectional! - * @param variablesMap | Variables map to use! - * @param values | Values list to use! - * - * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! - * - * @since 1.3.5 - */ - public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values) - { - return intoBidirectional(scopeToMakeBidirectional, variablesMap, values, null); - } - - /** - * @param scopeToMakeBidirectional | GenericScope to make bidirectional! - * @param variablesMap | Variables map to use! - * @param values | Values list to use! - * @param parent | Parent of scope! - * - * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! - * - * @since 1.3.5 - */ - public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values, GenericScope parent) - { - scopeToMakeBidirectional.variables = variablesMap; - scopeToMakeBidirectional.values = values; - scopeToMakeBidirectional.parent = parent; - return scopeToMakeBidirectional; - } - - /** - * @param map | Map to populate from kV array. - * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... - * - * @return Same map populated with kV array. - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public static > M mapKvArray(M map, Object... kVkVkV) - { - for (int i = 1; i < kVkVkV.length; i+=2) - map.put((K) kVkVkV[i-1], (V) kVkVkV[i]); - return map; - } -} +package org.ugp.serialx; + +import static org.ugp.serialx.utils.Utils.Instantiate; + +import java.io.Serializable; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Predicate; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; + +/** + * This collection is some sort of hybrid, or more accurately "union" between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
+ * Note: Variables are managed and accessed classically via {@link Map} methods such as put(KeyT key, Object) and array of independent values is accessed by via {@link List} methods such as add(Object) and get(int)
+ * Also this is java representation of JUSS GenericScope group such as: + *
+ * 
+ * {
+ *     //This is generic scope in JUSS! Variable keys are generic!
+ * }
+ * 
+ * 
+ * + * @author PETO + * + * @since 1.3.5 + * + * @param generic type of variables key. + * @param generic type of variables value and independent value. + */ +public class GenericScope implements Collection, Cloneable, Serializable +{ + private static final long serialVersionUID = 5717775602991055386L; + + protected Map variables; + protected List values; + protected GenericScope parent; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + @SafeVarargs + public GenericScope(ValT... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + @SafeVarargs + public GenericScope(Map variablesMap, ValT... values) + { + this(variablesMap, values == null ? null : Arrays.asList(values), null); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.2.0 + */ + public GenericScope(Map variablesMap, Collection values) + { + this(variablesMap, values, null); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + + * @since 1.2.0 + */ + public GenericScope(Map variablesMap, Collection values, GenericScope parent) + { + if (variablesMap != null) + this.variables = new LinkedHashMap<>(variablesMap); + if (values != null) + this.values = new ArrayList<>(values); + this.parent = parent; + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof GenericScope) + return values().equals(((GenericScope) obj).values()) && variables().equals(((GenericScope) obj).variables()); + if (obj instanceof Collection) + return variablesCount() <= 0 && values().equals(obj); + if (obj instanceof Map) + return valuesCount() <= 0 && variables().equals(obj); + if (obj != null && obj.getClass().isArray()) + return variablesCount() <= 0 && Objects.deepEquals(toArray(), Utils.fromAmbiguousArray(obj)); + return super.equals(obj); + } + + @Override + public String toString() + { + String name = getClass().getSimpleName(); + final int varCount; + if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0) + return name + (varCount > 0 ? variables() : values()); + return name + toUnifiedList(); + } + + @Override + public int hashCode() + { + final int varCount; + if ((varCount = variablesCount()) > 0 ^ valuesCount() > 0) + return (varCount > 0 ? variables() : values()).hashCode(); + return Objects.hash(variables(), values()); + } + + @SuppressWarnings("unchecked") + @Override + public GenericScope clone() + { + try + { + return clone(getClass()); + } + catch (Exception e) + { + return new GenericScope<>(variables(), values(), getParent()); + } + } + + /** + * @param typeOfClone | Class representing type of scope that will be created. + * @return Copy of this scope converted to instance of typeOfClone. + * + * @throws Exception | When program was unable to create instance of typeOfClone. + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public > S clone(Class typeOfClone) throws Exception + { + S clone = Instantiate(typeOfClone); + clone.values = (List) toValList(); + clone.variables = (Map) toVarMap(); + clone.parent = getParent(); + return (S) clone; + } + + /** + * @param newType | Type of new scope. + * @return Original scope retyped/casted into instance of newType. Similar to {@link GenericScope#clone(Class)} but this will share same instances of values list and variables map with original! + * + * @throws Exception | When program was unable to create instance of newType. + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public > S castTo(Class newType) throws Exception + { + if (getClass() == newType) + return (S) this; + + GenericScope clone = (GenericScope) Instantiate(newType); + clone.values = (List) values(); + clone.variables = (Map) variables(); + clone.parent = getParent(); + return (S) clone; + } + + /** + * @return Iterator of independent values. + * + * @since 1.2.0 + */ + @Override + public Iterator iterator() + { + return values().iterator(); + } + + /** + * Insert new variable. + * + * @param variableKey | Name of variable. + * @param variableValue | Variables value. + * + * @return Old value of variable with given name or null is there was no this variable before! + * + * @since 1.2.0 + */ + public ValT put(KeyT variableKey, ValT variableValue) + { + if (variableValue instanceof GenericScope && ((GenericScope) variableValue).getParent() == null) + ((GenericScope) variableValue).parent = this; + return variables().put(variableKey, variableValue); + } + + /** + * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... + * + * @return Array of values previously at keys from kv array. + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public ValT[] putAllKv(Object... kVkVkV) + { + ValT[] oldValues = (ValT[]) new Object[kVkVkV.length/2]; + for (int i = 1; i < kVkVkV.length; i+=2) { + oldValues[i/2] = put((KeyT) kVkVkV[i-1], (ValT) kVkVkV[i]); + } + return oldValues; + } + + /** + * @param index | Index of variable! + * + * @return Value of variable at required index or null if index was not found! + * + * @since 1.2.5 + */ + public V getVarAt(int index) + { + return getVarAt(index, null); + } + + /** + * @param index | Index of variable! + * @param defaultValue | Default value to return. + * + * @return Value of variable at required index or defaultValue if index was not found! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public V getVarAt(int index, V defaultValue) + { + int i = 0; + for (Map.Entry ent : varEntrySet()) + if (i++ == index) + return (V) ent.getValue(); + return defaultValue; + } + + /** + * @param variableKey | Variables name. + * + * @return Value of variable with name or null if there is no such a one! + * + * @since 1.2.0 + */ + public V get(KeyT variableKey) + { + return get(variableKey, null); + } + + /** + * @param variableKey | Variables name. + * @param defaultValue | Default value to return. + * + * @return Value of variable with name or defaultValue if there is no such a one (or given key contains null)! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public V get(KeyT variableKey, V defaultValue) + { + V obj; + if ((obj = (V) variables().get(variableKey)) == null) + return defaultValue; + return obj; + } + + /** + * @param pathToValue | Array with variables creating path to required value, nested in multiple sub-scopes. + * + * @return Value of variable at given path. If no path is given (length is 0) then this {@link GenericScope} will be returned.
+ * If 1 path argument is given then this behaves similarly to {@link GenericScope#get(Object)}.
+ * if 2+ path arguments are given then it will search the sub-scopes and return first match value. For example:
+ * In either way, if there is no suitable result then null will be returned!
+ * Consider this scope tree:
+ *
+	 * 
+	 * {
+	 *   125: {
+	 *   	"hello": {
+	 *   		"value" true
+	 *   	}
+	 *   }
+	 * }
+	 * 
+	 * 
+ * Then to get value of "value" you can do scope.get(125, "hello", "value")!
+ * If there is no other variable called "value" in the scope tree then you can also simplify it to scope.get("value"), but make sure that there is no equally-named variable!
+ * Note: Make sure that you are not calling {@link GenericScope#get(Object, Object)} by accident when you are using inline vargas array (unspecified count of arguments)! + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public V get(KeyT... pathToValue) + { + try + { + if (pathToValue.length <= 0) + return (V) this; + Object obj = get((KeyT) pathToValue[0]); + if (obj instanceof GenericScope) + return ((GenericScope) obj).get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); + for (Map.Entry var : varEntrySet()) + if (var.getValue() instanceof GenericScope) + try + { + GenericScope sc = (GenericScope) var.getValue(); + if ((sc = sc.getGenericScope(pathToValue[0])) != null) + return sc.get(pathToValue = Arrays.copyOfRange(pathToValue, 1, pathToValue.length)); + } + catch (Exception e) {} + + return (V) obj; + } + catch (ClassCastException e) + {} + return null; + } + + /** + * @param variableKey | Variables name. + * @param cls | Default value to return. + * @param defaultValue | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. + * + * @return Value of variable with name given converted to object of cls or defaultValue if there is no such a one (or given key contains null)! + * + * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! By default it uses {@link GenericScope#toObject(cls)} + * + * @since 1.3.8 + */ + public V get(KeyT variableKey, Class cls, V defaultValue) throws Exception + { + V obj = get(variableKey, defaultValue); + if (obj != null && obj.getClass() == cls) + return obj; + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(cls); + return obj; + } + + /** + * @param variableKey | Variables name to search for. + * + * @return True if variable with given name was found in this scope. + * + * @since 1.2.0 + */ + public boolean containsVariable(KeyT variableKey) + { + return variables().containsKey(variableKey); + } + + /** + * @param value | Object the independent value. + * + * @return True if independent value was found in this scope. + * + * @since 1.3.8 + */ + @Override + public boolean contains(Object value) + { + return values().contains(value); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Independent value with valueIndex of this {@link GenericScope}! + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public V get(int valueIndex) + { + return (V) values().get(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * @param cls | Class that you want the obtained object to be converted into! Exact conversion algorithm can differ based on its implementations. + * + * @return Independent value with valueIndex of this converted to object of cls! + * + * @throws Exception | If converting to object of cls failed from some reason! This can differ from implementation to implementation! + * + * @since 1.3.8 + */ + public V get(int valueIndex, Class cls) throws Exception + { + V obj = get(valueIndex); + if (obj != null && obj.getClass() == cls) + return obj; + if (obj instanceof GenericScope) + return ((GenericScope) obj).toObject(cls); + return obj; + } + + /** + * @param value | Independent value to add into array of values. + * + * @return {@link ArrayList#add(Object)} + * + * @since 1.2.0 + */ + @Override + public boolean add(ValT value) + { + boolean result = values().add(value); + if (result && value instanceof GenericScope && ((GenericScope) value).getParent() == null) + ((GenericScope) value).parent = this; + return result; + } + + /** + * @param values | List of independent value or values to add into array of values. + * + * @return {@link ArrayList#add(Object)} + * + * @since 1.2.0 + */ + @Override + public boolean addAll(Collection values) + { + if (values.isEmpty()) + return false; + return values().addAll((Collection) values); + } + + /** + * @param values | Array of independent value or values to add into array of values. + * + * @return {@link GenericScope#addAll(Object...)} + * + * @since 1.3.2 + */ + public boolean addAll(@SuppressWarnings("unchecked") ValT... values) + { + return addAll(Arrays.asList(values)); + } + + /** + * @param variables | Map of variables to put in. (Will use {@link Map#putAll(Map)}) + * + * @return This generic scope after the variables were added into it. + * + * @since 4.0.0 + */ + public GenericScope putAll(Map variables) + { + if (variables.isEmpty()) + return this; + variables().putAll(variables); + return this; + } + + /** + * @param values | Independent values to check. + * + * @return True all provided values are contained in this scope as independent values! + * + * @since 1.3.8 + */ + @Override + public boolean containsAll(Collection values) + { + return values().containsAll(values); + } + + /** + * @param values | Independent values to check. + * + * @return {@link Collection#removeAll(Collection)} for the independent values,,, + * + * @since 1.3.8 + */ + @Override + public boolean removeAll(Collection values) + { + return values().removeAll(values); + } + + /** + * @param values | Independent values to check. + * + * @return {@link Collection#retainAll(Collection)} for the independent values,,, + * + * @since 1.3.8 + */ + @Override + public boolean retainAll(Collection values) + { + return values().retainAll(values); + } + + /** + * @param scopeValueIndex | Index of sub-scopes value. + * + * @return Sub-scope on required index or null if there is no scope on required index!
+ * Note: Keep in mind that you need to insert valid index according to other values. Scopes share same index order with other values! + * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public GenericScope getGenericScope(int scopeValueIndex) + { + GenericScope obj = (GenericScope) get(scopeValueIndex); + if (obj instanceof GenericScope) + return (GenericScope) obj; + return null; + } + + /** + * @param pathToScope | Array with variables creating path to required scope. + * + * @return Sub-scope stored by variable with required name (last element of pathToScope) or null if there is no such a one in inserted path. If there is more than one result, the first one found will be returned! + * This search will also includes sub-scopes stored by variables of this scope while variables from lower ones are prioritize!
+ * If this function is called with no arguments then self will be returned! + * Note: Remember that this search includes variables only, no values!
+ * Note: Also remember that this function will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope}) + * + * @since 1.2.0 + */ + @SuppressWarnings("unchecked") + public GenericScope getGenericScope(K... pathToScope) + { + Object obj = get((KeyT[]) pathToScope); + if (obj instanceof GenericScope) + return (GenericScope) obj; + + if (containsVariable((KeyT) pathToScope[0])) + LogProvider.instance.logErr("Variable with name \"" + pathToScope[0] + "\" does exists! However its value is not instance of scope, use \"get\" function instead if possible!", null); + return null; + } + + /** + * @param type | Class of object to create (may or may not support other implementations of {@link Type}). + * + * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in {@link SerializationProtocol#REGISTRY}! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + public T toObject(Type type) throws Exception + { + return toObject(type, SerializationProtocol.REGISTRY); + } + + /** + * @param type | Class of object to create using protocols (may or may not support other implementations of {@link Type}). + * @param protocolsToUse | Registry of protocols to use. + * + * @return Object of class constructed from this scopes independent values using protocol for given class or null if there was no protocol found in protocolsToUse! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public T toObject(Type type, ProtocolRegistry protocolsToUse) throws Exception + { + if (protocolsToUse == null) + return null; + + Class objClass; + SerializationProtocol pro; + if ((pro = protocolsToUse.GetProtocolFor(objClass = (Class) type, SerializationProtocol.MODE_DESERIALIZE)) != null) + { + T obj; + if ((obj = pro.unserialize(objClass, variablesCount() > 0 ? new Object[] {this} : toArray())) != null) + return obj; + } + return null; + } + + /** + * @param predicate | Predicate object with filter condition in test method! + * + * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * + * @since 1.2.5 + */ + public GenericScope filter(Predicate predicate) + { + return filter(predicate, false); + } + + /** + * @param predicate | Predicate object with filter condition in test method! + * @param includeSubScopes | If true filtration will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Predicate#test(Object)}). + * If sub-scope is empty after filtration it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Scope after filtration using inserted predicate! If some object can't be casted to {@link Predicate#test(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public GenericScope filter(Predicate predicate, boolean includeSubScopes) + { + return (GenericScope) transform(new Function() + { + @Override + public Object apply(ValT t) + { + return predicate.test(t) ? t : DataParser.VOID; + } + }, includeSubScopes); + } + + /** + * @param trans | Function to transform objects of this scope! + * + * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! Sub-scopes are not included! + * + * @since 1.2.5 + */ + public GenericScope transform(Function trans) + { + return transform(trans, false); + } + + /** + * @param trans | Function to transform objects of this scope! + * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). + * If sub-scope is empty after transformation it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.2.5 + */ + @SuppressWarnings("unchecked") + public GenericScope transform(Function trans, boolean includeSubScopes) + { + if (trans == null || isEmpty()) + return (GenericScope) this; + + LinkedHashMap mappedVars = new LinkedHashMap<>(); + for (Entry ent : this.varEntrySet()) + try + { + Object obj = ent.getValue(); + if (includeSubScopes && obj instanceof GenericScope) + { + GenericScope sc = ((GenericScope) obj).transform(trans, includeSubScopes); + if (!sc.isEmpty()) + mappedVars.put(ent.getKey(), (V) sc); + } + else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) + mappedVars.put(ent.getKey(), trans.apply((ValT) obj)); + } + catch (ClassCastException e) + {} + + List mappedVals = map(trans, includeSubScopes); + try + { + GenericScope clone = Instantiate(getClass()); + clone.values = mappedVals; + clone.variables = mappedVars; + clone.parent = getParent(); + return clone; + } + catch (Exception e) + { + return new GenericScope<>(mappedVars, mappedVals, getParent()); + } + } + + /** + * @param trans | Function to transform independent objects of this scope! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.3.5 + */ + public List map(Function trans) + { + return map(trans, false); + } + + /** + * @param trans | Function to transform independent objects of this scope! + * @param includeSubScopes | If true transformation will be also applied on sub-scopes, if false sub-scopes will be treated as other things (parsed in to {@link Function#apply(Object)}). + * If sub-scope is empty after transformation it will not be included in result! + * Note: Remember that this will work only when this scope generically allows to store other scopes inside (when ValT is base class of {@link GenericScope})! + * + * @return Original scope after transformation using inserted function! If some object can't be casted to {@link Function#apply(Object)} argument, it will be treated as invalid and will be filtered away! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public List map(Function trans, boolean includeSubScopes) + { +// List mapped = new ArrayList<>(size()); +// for (Object obj : this) +// try +// { +// if (obj instanceof GenericScope && includeSubScopes) +// { +// GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); +// if (!sc.isEmpty()) +// mapped.add((V) sc); +// } +// else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) +// mapped.add((V) obj); +// } +// catch (ClassCastException e) +// {} + + List mapped = (List) toValList(); + for (int i = valuesCount()-1; i >= 0; i--) + { + try + { + Object obj = mapped.get(i); + if (includeSubScopes && obj instanceof GenericScope) + { + GenericScope sc = (GenericScope) ((GenericScope) obj).map(trans, includeSubScopes); + if (!sc.isEmpty()) + { + mapped.set(i, (V) sc); + continue; + } + } + else if ((obj = trans.apply((ValT) obj)) != DataParser.VOID) + { + mapped.set(i, (V) obj); + continue; + } + } + catch (ClassCastException e) + {} + + mapped.remove(i); + } + + return mapped; + } + + /** + * @param valueIndex | Index of independent value to remove! + * + * @return Removed independent value! + * + * @since 1.3.2 + */ + public ValT remove(int valueIndex) + { + return values().remove(valueIndex < 0 ? valuesCount() + valueIndex : valueIndex); + } + + /** + * @param independentValue | Independent value to remove! + * + * @return Value of variable that was removed! + * + * @since 1.3.8 + */ + @Override + public boolean remove(Object independentValue) + { + return values().remove(independentValue); + } + + /** + * @param variableKey | Name of variable to remove! + * + * @return Value of variable that was removed! + * + * @since 1.3.8 + */ + public ValT removeVariable(KeyT variableKey) + { + return variables().remove(variableKey); + } + + /** + * Removes all independent values and variables of this scope! + *
+ * Basically it just calls variables().clear() and values().clear()! + * + * @since 1.3.5 + */ + @Override + public void clear() + { + if (variables != null) + variables.clear(); + if (values != null) + values.clear(); + } + + /** + * @return This scope after inheriting variables of its parent (return this)! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public GenericScope inheritParent() + { + GenericScope parent = getParent(); + if (parent != null) + variables().putAll((Map) parent.variables()); + return this; + } + + /** + * @param scope | GenericScope whose content will be added! + * + * @return This scope... + * + * @since 1.3.0 + */ + public GenericScope addAll(GenericScope scope) + { + values().addAll(scope.values()); + variables().putAll(scope.variables()); + return this; + } + + /** + * @return Entry set of variables! + * + * @since 1.2.0 + */ + public Set> varEntrySet() + { + return variables().entrySet(); + } + + /** + * @return Count of keyless values of this scope! (values().size()) + * + * @since 1.2.0 + */ + public int valuesCount() + { + return values().size(); + } + + /** + * @return Count of variables! (variables().size()) + * + * @since 1.2.0 + */ + public int variablesCount() + { + return variables().size(); + } + + /** + * @return Total number of variables and independent values of this scope! (vvaluesCount() + variablesCount()) + * + * @since 1.3.8 (before 1.3.8 known as totalSize) + */ + @Override + public int size() + { + return valuesCount() + variablesCount(); + } + + /** + * @return True if this scope is completely empty, meaning there are no variables or values. + * + * @since 1.2.0 + */ + @Override + public boolean isEmpty() + { + return size() <= 0; + } + + /** + * @return The parent scope of this scope or null if this scope has no parent such as default one in file.
+ * Note: This may or may not be always null based on the way this scope was instantiated... + * + * @since 1.2.0 + */ + public > T getParent() + { + return getParent(1); + } + + /** + * @param depth | Positive number representing how many times will this method call itself...
For example 0 or less = this, 1 = parent, 2 = parentOfParent (parent.getParent()) and so on... + * If you want to get the root parent (the one that has no parent), simply put a big number as depth. 99 should be enough! + * + * @return The parent scope based on depth or null if this scope has no parent which means its already root (default one in file). + * If depth was bigger than 1, null will not be returned, last not null parent will be returned instead!
+ * Note: This may or may not be always null based on the way this scope was instantiated... + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public > T getParent(int depth) + { + if (depth < 1) + return (T) this; + + GenericScope parentsParent; + if (depth == 1 || parent == null || (parentsParent = parent.getParent(--depth)) == null) + return (T) parent; + return (T) parentsParent; + } + + /** + * @return New {@link LinkedHashMap} with variables of this a in defined order! Key is a KeyT of variable and value is its value!
+ * Modifying this map will not affect this GenericScope object! + * + * @since 1.2.0 + */ + public LinkedHashMap toVarMap() + { + return new LinkedHashMap<>(variables()); + } + + /** + * @return New {@link ArrayList} with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this GenericScope object!
+ * Note: Returning other {@link List} implementations than {@link ArrayList} (or other collection that stores elements in "array-like fashion") may result in serious performance implications! Queues or LinkedLists are the prime examples to avoid! + * + * @since 1.2.0 + */ + public List toValList() + { + return new ArrayList<>(values()); + } + + /** + * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this {@link GenericScope} object! + * + * @since 1.3.8 (before 1.3.8 known as toValArray) + */ + @Override + public Object[] toArray() + { + return values().toArray(); + } + + /** + * @param vals | Array to store independent values into! + * + * @return Primitive array with independent values of this {@link GenericScope}. These values have nothing to do with values of variables, they are independent! + * Modifying this list will not affect this {@link GenericScope} object! + * + * @since 1.3.8 (before 1.3.8 known as toValArray) + */ + @Override + public T[] toArray(T[] vals) + { + return values().toArray(vals); + } + + /** + * @return List with both variables and values! Variables will be added as {@link Entry}! + * Variables will be always first! + * Modifying this map will not affect this GenericScope object! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public List toUnifiedList() + { + List list = (List) toValList(); + list.addAll(0, varEntrySet()); + return list; + } + + /** + * @return Independent values of this scope. These are not the values of keys these are values that have no key. You can access them via {@link GenericScope#get(int)}! + * Note: Editing this List will affect this scope! + * + * @since 1.2.0 + */ + public List values() + { + if (values == null) + values = new ArrayList<>(); + return values; + } + + /** + * @return Variables of this scope. Objecthis variables has nothing to do with values. Key is a KeyT name of variable and value is value of variable. + * Note: Editing this Map will affect this scope! + * + * @since 1.2.0 + */ + public Map variables() + { + if (variables == null) + variables = new LinkedHashMap<>(); + return variables; + } + + /** + * @param variablesMap | Variables map to use! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap) + { + return newBidirectional(variablesMap, null); + } + + /** + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap, List values) + { + return newBidirectional(variablesMap, values, null); + } + + /** + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * @param parent | Parent of scope! + * + * @return New scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static GenericScope newBidirectional(Map variablesMap, List values, GenericScope parent) + { + return intoBidirectional(new GenericScope<>(null, null, null), variablesMap, values, parent); + } + + /** + * @param scopeToMakeBidirectional | GenericScope to make bidirectional! + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * + * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values) + { + return intoBidirectional(scopeToMakeBidirectional, variablesMap, values, null); + } + + /** + * @param scopeToMakeBidirectional | GenericScope to make bidirectional! + * @param variablesMap | Variables map to use! + * @param values | Values list to use! + * @param parent | Parent of scope! + * + * @return Inserted scope that is bidirectional with given data structures (list and map), which means that changing these data structures will affect scope and changing scope will affect data structures. This is behavior that regular constructor created scopes do not possess! + * + * @since 1.3.5 + */ + public static > S intoBidirectional(S scopeToMakeBidirectional, Map variablesMap, List values, GenericScope parent) + { + scopeToMakeBidirectional.variables = variablesMap; + scopeToMakeBidirectional.values = values; + scopeToMakeBidirectional.parent = parent; + return scopeToMakeBidirectional; + } + + /** + * @param map | Map to populate from kV array. + * @param kVkVkV | kV array with keys and values to insert into this map. Elements with even indexes are values and the ones with odd indexes are keys... + * + * @return Same map populated with kV array. + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public static > M mapKvArray(M map, Object... kVkVkV) + { + for (int i = 1; i < kVkVkV.length; i+=2) + map.put((K) kVkVkV[i-1], (V) kVkVkV[i]); + return map; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java b/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java index 4b38dd8..c0aca1e 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/MultimediaSerializer.java @@ -1,216 +1,216 @@ -package org.ugp.serialx; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import java.util.Collection; -import java.util.Map; - -/** - * Interface with common methods for serializing and deserializing/loading contents from various types of media ({@link File}, {@link InputStream}, {@link Appendable}, {@link Reader} etc...).
- * Intended/recommended use is to implement this together with some sort of {@link Collection} or {@link Map} and/or something that can be treated as such. - * - * @param Type of the object that is serialized and deserialized, you likely want this to be the class (or patent class) of an implementor of this interface. - * - * @author PETO - * - * @since 4.0.0 (Separated from {@link Serializer} in 4.0.0) - */ -public interface MultimediaSerializer -{ - /** - * @param f | File to write in. This must be a text file. - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @throws IOException if file can't be opened or serialization fails! - * - * @since 1.1.5 - */ - default void serializeTo(File f, Object... args) throws IOException - { - serializeTo(false, f, args); - } - - /** - * @param append | When true, the new objects will be appended to files content (same objects will be also appended if there are some)! - * @param f | File to write in. This must be a text file. - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @throws IOException if file can't be opened or serialization fails! - * - * @since 1.1.5 - * - * @see MultimediaSerializer#serializeTo(Appendable, Object...) - */ - default void serializeTo(boolean append, File f, Object... args) throws IOException - { - //double t0 = System.nanoTime(); - try (Writer writer = new BufferedWriter(new FileWriter(f, append))) - { - serializeTo(writer, args); - } - -// String serialized = stringify(args); -// -// RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); -// FileChannel channel = fileOutputStream.getChannel(); -// -//// channel.write(ByteBuffer.wrap(serialized.getBytes())); -// -// ByteBuffer buff = channel.map(FileChannel.MapMode.READ_WRITE, append ? channel.size() : 0, serialized.length()); -// buff.put(serialized.getBytes()); -// -// channel.force(true); -// channel.close(); -// fileOutputStream.close(); - } - - /** - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return String with the respective contents serialized in specific format. - * - * @throws RuntimeException IOException, but it should not occur in this case... - * - * @since 1.0.0 - * - * @see MultimediaSerializer#serializeTo(Appendable, Object...) - */ - default String stringify(Object... args) - { - try - { - return serializeTo(new StringBuilder(), args).toString(); - } - catch (IOException e) - { - throw new RuntimeException(e); // Should not occur... - } - } - - /** - * @param outputStream | Source {@link OutputStream} to serialize the respective contents into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Source {@link OutputStream} with respective contents serialized in specific format (may or may not be flushed). - * - * @throws IOException When appending the {@link OutputStream} throws.... - * - * @since 1.3.2 - * - * @see MultimediaSerializer#serializeTo(Appendable, Object...) - */ - default OutputStream serializeTo(OutputStream outputStream, Object... args) throws IOException - { - serializeTo(new OutputStreamWriter(outputStream), args); - return outputStream; - } - - /** - * @param source | Source {@link Appendable} to serialize respective contents into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Source {@link Appendable} with respective contents serialized in specific format (depends on the implementation). - * - * @throws IOException depends on the implementation (likely when the provided source throws). - * - * @since 1.3.2 - */ - A serializeTo(A source, Object... args) throws IOException; - - /** - * @param source | Source {@link Appendable} to serialize respective contents into! - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. - * - * @since 1.3.5 - */ - default A serializeAsSubscope(A source, Object... args) throws IOException - { - return serializeAsSubscope(source, new char[] {'{', '}'}, args); - } - - /** - * @param source | Source {@link Appendable} to serialize respective contents into! - * @param wrappingBrackets | Array of 2 characters to wrap content inside (opening and closing one). - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. - * - * @since 1.3.5 - */ - A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException; - - /** - * @param file | Text file with serialized contents in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized contents represented by object T (may or may not be "this")! - * - * @throws IOException if file does not exist or cannot be read! - * - * @since 1.0.0 - * - * @see MultimediaSerializer#loadFrom(Reader, Object...) - */ - default S loadFrom(File file, Object... parserArgs) throws IOException - { - return loadFrom(new FileReader(file), parserArgs); - } - - /** - * @param str | {@link CharSequence} with serialized contents in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized contents represented by object T (may or may not be "this")! - * - * @throws IOException When reading the char sequence fails... - * - * @since 1.2.5 - * - * @see MultimediaSerializer#loadFrom(Reader, Object...) - */ - default S loadFrom(CharSequence str, Object... parserArgs) throws IOException - { - return loadFrom(new StringReader(str.toString()), parserArgs); - } - - /** - * @param stream | Any {@link InputStream} with serialized contents in specific format to load. - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized contents represented by object T (may or may not be "this")! - * - * @throws IOException When reading the input stream fails... - * - * @since 1.3.2 - * - * @see MultimediaSerializer#loadFrom(Reader, Object...) - */ - default S loadFrom(InputStream stream, Object... parserArgs) throws IOException - { - return loadFrom(new InputStreamReader(stream), parserArgs); - } - - /** - * @param reader | Reader to read the with serialized contents from! - * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! - * - * @return Unserialized contents represented by object T (may or may not be "this". If T is instanceof this Class, you most likely want to return "this")! - * - * @throws IOException When reading the reader fails... - * - * @since 1.3.2 - */ - S loadFrom(Reader reader, Object... parserArgs) throws IOException; -} +package org.ugp.serialx; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileReader; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringReader; +import java.io.Writer; +import java.util.Collection; +import java.util.Map; + +/** + * Interface with common methods for serializing and deserializing/loading contents from various types of media ({@link File}, {@link InputStream}, {@link Appendable}, {@link Reader} etc...).
+ * Intended/recommended use is to implement this together with some sort of {@link Collection} or {@link Map} and/or something that can be treated as such. + * + * @param Type of the object that is serialized and deserialized, you likely want this to be the class (or patent class) of an implementor of this interface. + * + * @author PETO + * + * @since 4.0.0 (Separated from {@link Serializer} in 4.0.0) + */ +public interface MultimediaSerializer +{ + /** + * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + */ + default void serializeTo(File f, Object... args) throws IOException + { + serializeTo(false, f, args); + } + + /** + * @param append | When true, the new objects will be appended to files content (same objects will be also appended if there are some)! + * @param f | File to write in. This must be a text file. + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @throws IOException if file can't be opened or serialization fails! + * + * @since 1.1.5 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default void serializeTo(boolean append, File f, Object... args) throws IOException + { + //double t0 = System.nanoTime(); + try (Writer writer = new BufferedWriter(new FileWriter(f, append))) + { + serializeTo(writer, args); + } + +// String serialized = stringify(args); +// +// RandomAccessFile fileOutputStream = new RandomAccessFile(f, "rw"); +// FileChannel channel = fileOutputStream.getChannel(); +// +//// channel.write(ByteBuffer.wrap(serialized.getBytes())); +// +// ByteBuffer buff = channel.map(FileChannel.MapMode.READ_WRITE, append ? channel.size() : 0, serialized.length()); +// buff.put(serialized.getBytes()); +// +// channel.force(true); +// channel.close(); +// fileOutputStream.close(); + } + + /** + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return String with the respective contents serialized in specific format. + * + * @throws RuntimeException IOException, but it should not occur in this case... + * + * @since 1.0.0 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default String stringify(Object... args) + { + try + { + return serializeTo(new StringBuilder(), args).toString(); + } + catch (IOException e) + { + throw new RuntimeException(e); // Should not occur... + } + } + + /** + * @param outputStream | Source {@link OutputStream} to serialize the respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link OutputStream} with respective contents serialized in specific format (may or may not be flushed). + * + * @throws IOException When appending the {@link OutputStream} throws.... + * + * @since 1.3.2 + * + * @see MultimediaSerializer#serializeTo(Appendable, Object...) + */ + default OutputStream serializeTo(OutputStream outputStream, Object... args) throws IOException + { + serializeTo(new OutputStreamWriter(outputStream), args); + return outputStream; + } + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Source {@link Appendable} with respective contents serialized in specific format (depends on the implementation). + * + * @throws IOException depends on the implementation (likely when the provided source throws). + * + * @since 1.3.2 + */ +
A serializeTo(A source, Object... args) throws IOException; + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. + * + * @since 1.3.5 + */ + default A serializeAsSubscope(A source, Object... args) throws IOException + { + return serializeAsSubscope(source, new char[] {'{', '}'}, args); + } + + /** + * @param source | Source {@link Appendable} to serialize respective contents into! + * @param wrappingBrackets | Array of 2 characters to wrap content inside (opening and closing one). + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized contents as the inner/nested sub-scope of this {@link MultimediaSerializer}! Wrapped inside of corresponding wrappingBrackets (default { and })! This is more usecase specific, mainly useful with treelike structures. + * + * @since 1.3.5 + */ + A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException; + + /** + * @param file | Text file with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException if file does not exist or cannot be read! + * + * @since 1.0.0 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(File file, Object... parserArgs) throws IOException + { + return loadFrom(new FileReader(file), parserArgs); + } + + /** + * @param str | {@link CharSequence} with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException When reading the char sequence fails... + * + * @since 1.2.5 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(CharSequence str, Object... parserArgs) throws IOException + { + return loadFrom(new StringReader(str.toString()), parserArgs); + } + + /** + * @param stream | Any {@link InputStream} with serialized contents in specific format to load. + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this")! + * + * @throws IOException When reading the input stream fails... + * + * @since 1.3.2 + * + * @see MultimediaSerializer#loadFrom(Reader, Object...) + */ + default S loadFrom(InputStream stream, Object... parserArgs) throws IOException + { + return loadFrom(new InputStreamReader(stream), parserArgs); + } + + /** + * @param reader | Reader to read the with serialized contents from! + * @param parserArgs | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (probably used for formating of incoming information)! + * + * @return Unserialized contents represented by object T (may or may not be "this". If T is instanceof this Class, you most likely want to return "this")! + * + * @throws IOException When reading the reader fails... + * + * @since 1.3.2 + */ + S loadFrom(Reader reader, Object... parserArgs) throws IOException; +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index de37137..bfc0152 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -1,737 +1,737 @@ -package org.ugp.serialx; - -import static org.ugp.serialx.utils.Utils.Instantiate; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.multilpy; -import static org.ugp.serialx.utils.Utils.post; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.lang.reflect.Type; -import java.net.HttpURLConnection; -import java.net.URI; -import java.net.URL; -import java.net.URLConnection; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -import java.util.function.Function; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.StringConverter; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Registry; - -/** - * {@link org.ugp.serialx.Serializer} is powerful abstract class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s. - * This class itself is responsible for formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage! - * It is instance of {@link Scope} so we can say that this is scope that can serialize itself using system of already mentioned {@link DataParser} and {@link SerializationProtocol}! - * - * @author PETO - * - * @since 1.0.0 - */ -@SuppressWarnings("serial") -public abstract class Serializer extends Scope implements MultimediaSerializer -{ - /** - * Common parsers that can parse primitive datatypes! - * - * @since 1.3.2 - */ - public static final ParserRegistry COMMON_PARSERS = DataParser.REGISTRY.clone(); - - protected ParserRegistry parsers; - protected ProtocolRegistry protocols; - - protected byte format = 0; - - /** - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public Serializer(Object... values) - { - this(null, values); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public Serializer(Map variablesMap, Object... values) - { - this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); - } - - /** - * @param sourceScope | Scope with initial content! - * - * @since 1.3.5 - */ - public Serializer(GenericScope sourceScope) - { - this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public Serializer(Map variablesMap, Collection values) - { - this(null, variablesMap, values); - } - - /** - * @param parsers | Registry of parsers to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public Serializer(Registry parsers, Map variablesMap, Collection values) - { - this(parsers, null, variablesMap, values, null); - } - - /** - * @param parsers | Registry of parsers to use! - * @param protocols | Registry of protocols to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * @param parent | Parent of this scope. - * - * @since 1.3.2 - */ - public Serializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) - { - super(variablesMap, values, parent); - if (parsers != null) - setParsers(parsers); - if (protocols != null) - setProtocols(protocols); - } - - @Override - public > S clone(Class typeOfClone) throws Exception - { - S clone = super.clone(typeOfClone); - if (clone instanceof Serializer) - { - ((Serializer) clone).setParsers(getParsers()); - ((Serializer) clone).setProtocols(getProtocols()); - } - return clone; - } - - @Override - public > S castTo(Class newType) throws Exception - { - S clone = super.castTo(newType); - if (clone instanceof Serializer) - { - ((Serializer) clone).setParsers(getParsers()); - ((Serializer) clone).setProtocols(getProtocols()); - } - return clone; - } - - @Override - public T toObjectOf(String variableWithscope, Class objClass, T defaultValue) throws Exception - { - return toObjectOf(variableWithscope, objClass, defaultValue, getProtocols()); - } - - /** - * @param objClass | Class of object to create (may or may not support other implementations of {@link Type}). - * - * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in this {@link Serializer#getProtocols()}! - * - * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! - * - * @since 1.2.5 - */ - @Override - public T toObject(Type objClass) throws Exception - { - return toObject(objClass, getProtocols()); - } - - @SuppressWarnings("unchecked") - @Override - public GenericScope transform(Function trans, boolean includeSubScopes) - { - Serializer transformed = (Serializer) super.transform(trans, includeSubScopes); - transformed.parsers = getParsers(); - transformed.protocols = getProtocols(); - return (GenericScope) transformed; - } - - /** - * @see Serializer#into(Object, Serializer, String...) - */ - @Override - public T into(T obj, String... fieldNamesToUse) throws IntrospectionException, Exception - { - return Serializer.into(obj, this, fieldNamesToUse); - } - - /** - * @deprecated (1.3.9) DO NOT USE THIS, USE VARIATION OF {@link AbstractMap.SimpleEntry} OR {@link VariableConverter#NewVariable(String, Object)} FROM serialx-juss module INSTEAD! - * - * @param name | Name of variable. - * @param value | Value of variable. - * - * @return Classic variable expression in general form like [name] = [value]. - * - * @since 1.1.5 - */ - @Deprecated - public String Var(String name, T value) - { - return Code(name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), false) + ";"); - } - - /** - * @param comment | The comment... - * - * @return Comment in general form, such as //comment
Each line will be taken as new comment! - * - * @since 1.1.5 - */ - public String Comment(String comment) - { - StringBuilder sb = new StringBuilder(); - String[] lines = comment.split("\n"); - for (int i = 0; i < lines.length; i++) - sb.append("//" + lines[i] + (i < lines.length - 1 ? "\n" : "")); - return Code(sb); - } - - /** - * - * @param code | Code to convert into JUSS (StringConverter) code form. - * @return "${" + code + "} - *

Note: This works only in combination with {@link StringConverter}! - * - * @since 1.1.5 - * - * @see StringConverter#DirectCode(Object) - */ - public String Code(Object code) - { - return StringConverter.DirectCode(code); - } - - /** - * @param serialize | If true, this scope will be serialized to string! - * - * @return This scope as string! - * - * @since 1.3.2 - * - * @see Serializer#stringify(Object...) - */ - public String toString(boolean serialize) - { - if (serialize) - return stringify(); - return super.toString(); - } - - /** - * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! - * - * @throws Exception When creating the new instance fails... - * - * @since 1.3.2 - */ - public Serializer emptyClone() throws Exception - { - return emptyClone(this); - } - - /** - * @param parent | Parent scope of new Serializer instance! - * - * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! - * - * @throws Exception When creating the new instance fails... - * - * @since 1.3.2 - */ - public Serializer emptyClone(Scope parent) throws Exception - { - return emptyClone(getClass(), parent); - } - - /** - * @param typeOfClone | Specific type of the clone (has to extend Serializer). - * @param parent | Parent scope of new Serializer instance! - * - * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! - * - * @throws Exception When creating the new instance fails... - * - * @since 1.3.5 - */ - public T emptyClone(Class typeOfClone, GenericScope parent) throws Exception - { - return emptyClone(Instantiate(typeOfClone), parent); - } - - /** - * @param newEmptyInstance | Manually inserted brand new empty instance of this scope! - * @param parent | Parent scope of new Serializer instance! - * - * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! - * - * @since 1.3.5 - */ - public T emptyClone(T newEmptyInstance, GenericScope parent) - { - newEmptyInstance.setParsers(getParsers()); - newEmptyInstance.setProtocols(getProtocols()); - newEmptyInstance.setFormat(getFormat()); - newEmptyInstance.parent = parent; - return newEmptyInstance; - } - - @Override - public Scope clone() - { - Scope scope = super.clone(); - if (scope instanceof Serializer) - { - ((Serializer) scope).setParsers(getParsers()); - ((Serializer) scope).setProtocols(getProtocols()); - ((Serializer) scope).setFormat(getFormat()); - } - return scope; - } - - /** - * @return {@link Registry} with parsers that this {@link Serializer} uses! - * - * @since 1.3.2 - */ - public ParserRegistry getParsers() - { - if (parsers == null) - parsers = COMMON_PARSERS.clone(); - return parsers; - } - - /** - * @param parsers | Registry with parsers to set! - * - * @since 1.3.2 - */ - public void setParsers(Registry parsers) - { - setParsers(parsers instanceof ParserRegistry ? (ParserRegistry) parsers : new ParserRegistry(parsers)); - } - - /** - * @param parsers | Registry with parsers to set! - * - * @since 1.3.5 - */ - public void setParsers(ParserRegistry parsers) - { - this.parsers = (ParserRegistry) parsers; - } - - /** - * @return {@link ProtocolRegistry} with serialization protocols that this {@link Serializer} uses! - * - * @since 1.3.2 - */ - public ProtocolRegistry getProtocols() - { - if (protocols == null) - protocols = SerializationProtocol.REGISTRY.clone(); - return protocols; - } - - /** - * @param protocols | ProtocolRegistry with serialization protocols to set! - * - * @since 1.3.2 - */ - public void setProtocols(ProtocolRegistry protocols) - { - this.protocols = protocols; - } - - /** - * @param parser | DataParser to add! - * - * @return DataParser if was added! - * - * @since 1.3.2 - */ - public DataParser addParser(DataParser parser) - { - if (getParsers().add(parser)) - return parser; - return null; - } - - /** - * @param protocol | SerializationProtocol to add! - * - * @return SerializationProtocol if was added! - * - * @since 1.3.2 - */ - public SerializationProtocol addProtocol(SerializationProtocol protocol) - { - if (getProtocols().add(protocol)) - return protocol; - return null; - } - - /** - * This will transform this Serializer and whole tree of its sub-scopes into regular {@link Scope}s! - * Remember that scope is just a data container and analyzer and it can't be serialized in contrast to serializer! - * - * @return This serializer transformed in to simple {@link Scope}! - * - * @since 1.3.2 - */ - public GenericScope transformToScope() - { - Function transFunction = new Function() - { - @Override - public Object apply(Object t) - { - if (t instanceof Serializer) - { - GenericScope srl = ((Scope) t).transform(this); - return new Scope(srl.variables(), srl.values(), srl.getParent()); - } - return t; - } - }; - return (GenericScope) transform(transFunction); - } - - /** - * @param source | Source {@link Appendable} to serialize variables and objects into! - * @param wrappingBrackets | Array of 2 characters to wrap content inside - * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! - * - * @return Serialized content of this scope as inner sub-scope of this scope! Wrapped inside of corresponding wrappingBrackets (default { and })! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public
A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException - { - source.append(wrappingBrackets[0]); - if (isEmpty()) - return (A) source.append(wrappingBrackets[1]); - - if (format == 0) // No format... - { - if (args.length > 1 && args[1] instanceof Integer) - args[1] = ((int) args[1]) + 1; - return (A) serializeTo(source, args).append(wrappingBrackets[1]); - } - - int tabs; - if (args.length > 1 && args[1] instanceof Integer) - args[1] = (tabs = (int) args[1]) + 1; - else - tabs = 0; - - return (A) serializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)) - .append(wrappingBrackets[1]); - } - - /** - * @param indexWithStringValue | Index of independent value that should be string. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from string at given index, using parsers of this {@link Serializer}! - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public T getParsed(int indexWithStringValue, Object... args) - { - return (T) getParsers().parse(getString(indexWithStringValue), args); - } - - /** - * @param variableWithStringValue | Variable name with string value. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from value of given variable, using parsers of this {@link Serializer}! - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public T getParsed(String variableWithStringValue, Object... args) - { - return (T) getParsers().parse(getString(variableWithStringValue), args); - } - - /** - * @return Non 0 value if proper indentation and newline characters should be used when serializing. Default is 0, no formating... - * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} - * - * @since 1.3.9 - */ - public byte getFormat() - { - return format; - } - - /** - * @param format | A non 0 value if proper indentation and newline characters should be used when serializing. - * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} - * - * @since 1.3.9 - */ - public void setFormat(byte format) - { - this.format = format; - } - - /** - * @param obj | Object to map the serializer variables into! - * @param fromSerializer | Source serializer to map obj from! - * @param fieldNamesToUse | Array of obj field names to map/populate from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! - * - * @return Same obj after being populated/mapped by contents of fromSerializer via requested fields (fieldNamesToUse) and conversion rules listed below! - * Table of specific Serializer --> Object conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (obj) typeAction with obj
{@link File}{@link Serializer#serializeTo(File, Object...)}
{@link Appendable}{@link Serializer#serializeTo(Appendable, Object...)}
{@link OutputStream}{@link Serializer#serializeTo(OutputStream, Object...)}
{@link URL}Serializer (fromSerializer) will open connection with {@link URL} and attempt serialize its content to it if possible!
{@link URLConnection}Serializer (fromSerializer) will attempt serialize its content into given {@link URLConnection} if possible!
{@link CharSequence} (as http address)Serializer (fromSerializer) will open connection with url and get + serialize the content into it if possible!
Others (default){@link Scope#into(Object, GenericScope, String...)} (return description)
- - * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during serialization! - * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public static T into(Object obj, Serializer fromSerializer, String... fieldNamesToUse) throws Exception, IntrospectionException - { - if (obj instanceof File) - { - fromSerializer.serializeTo((File) obj); - return (T) obj; - } - - if (obj instanceof Appendable) - { - fromSerializer.serializeTo((Appendable) obj); - return (T) obj; - } - - if (obj instanceof OutputStream) - { - fromSerializer.serializeTo((OutputStream) obj); - return (T) obj; - } - - if (obj instanceof URL) - { - URLConnection con = ((URL) obj).openConnection(); - con.setDoOutput(true); - if (con instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) con); - else - fromSerializer.serializeTo(con.getOutputStream()); - return (T) con; - } - - if (obj instanceof URLConnection) - { - if (obj instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) obj); - else - fromSerializer.serializeTo(((URLConnection) obj).getOutputStream()); - return (T) obj; - } - - try - { - if (obj instanceof CharSequence) - { - if (indexOfNotInObj((CharSequence) obj, "http") == 0) - { - URLConnection con = new URI(obj.toString()).toURL().openConnection(); - con.setDoOutput(true); - if (con instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) con); - else - fromSerializer.serializeTo(con.getOutputStream()); - return (T) con; - } - - try - { - File file = new File(obj.toString()); - fromSerializer.serializeTo(file); - return (T) file; - } - catch (Exception e) - {} - } - } - catch (IOException e) - {} - - return (T) Scope.into(obj, fromSerializer, fieldNamesToUse); - } - - /** - * @param newInstance | New instance of specific {@link Serializer} - * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! - * - * @return {@link Serializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

- * Table of specific Object --> Serializer conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
- * - * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went very wrong during deserialization! - * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! - * @throws RuntimeException in case of something went wrong during deserialization process and {@link LogProvider#isReThrowException()} is set to true! - * - * @since 1.3.5 - */ - public static Serializer from(Serializer newInstance, Object fromObj, String... fieldNamesToUse) throws Exception, IntrospectionException - { - if (fromObj instanceof CharSequence) - { - try - { - String fromStr; - if (indexOfNotInObj(fromStr = fromObj.toString(), "http") == 0) - return newInstance.loadFrom(new URI(fromStr).toURL().openStream()); - return newInstance.loadFrom(new File(fromStr)); - } - catch (Exception e) - { - if (e instanceof RuntimeException) - throw e; - } - - return newInstance.loadFrom((CharSequence) fromObj); - } - - if (fromObj instanceof File) - return newInstance.loadFrom((File) fromObj); - if (fromObj instanceof Reader) - return newInstance.loadFrom((Reader) fromObj); - if (fromObj instanceof InputStream) - return newInstance.loadFrom((InputStream) fromObj); - if (fromObj instanceof URL) - return newInstance.loadFrom(((URL) fromObj).openStream()); - if (fromObj instanceof URLConnection) - return newInstance.loadFrom(((URLConnection) fromObj).getInputStream()); - - newInstance.addAll(Scope.from(fromObj, fieldNamesToUse)); - return newInstance; - } +package org.ugp.serialx; + +import static org.ugp.serialx.utils.Utils.Instantiate; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.Utils.post; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.lang.reflect.Type; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.net.URLConnection; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.function.Function; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; + +/** + * {@link org.ugp.serialx.Serializer} is powerful abstract class that allows you to serialize any object in Java using custom data format compiled by recursive descent parser consisting of {@link DataParser}s. + * This class itself is responsible for formating and managing input-output (IO) of content obtained from parsers and protocols as well as their management of their usage! + * It is instance of {@link Scope} so we can say that this is scope that can serialize itself using system of already mentioned {@link DataParser} and {@link SerializationProtocol}! + * + * @author PETO + * + * @since 1.0.0 + */ +@SuppressWarnings("serial") +public abstract class Serializer extends Scope implements MultimediaSerializer +{ + /** + * Common parsers that can parse primitive datatypes! + * + * @since 1.3.2 + */ + public static final ParserRegistry COMMON_PARSERS = DataParser.REGISTRY.clone(); + + protected ParserRegistry parsers; + protected ProtocolRegistry protocols; + + protected byte format = 0; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public Serializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Map variablesMap, Collection values) + { + this(null, variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public Serializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, null, variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public Serializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(variablesMap, values, parent); + if (parsers != null) + setParsers(parsers); + if (protocols != null) + setProtocols(protocols); + } + + @Override + public > S clone(Class typeOfClone) throws Exception + { + S clone = super.clone(typeOfClone); + if (clone instanceof Serializer) + { + ((Serializer) clone).setParsers(getParsers()); + ((Serializer) clone).setProtocols(getProtocols()); + } + return clone; + } + + @Override + public > S castTo(Class newType) throws Exception + { + S clone = super.castTo(newType); + if (clone instanceof Serializer) + { + ((Serializer) clone).setParsers(getParsers()); + ((Serializer) clone).setProtocols(getProtocols()); + } + return clone; + } + + @Override + public T toObjectOf(String variableWithscope, Class objClass, T defaultValue) throws Exception + { + return toObjectOf(variableWithscope, objClass, defaultValue, getProtocols()); + } + + /** + * @param objClass | Class of object to create (may or may not support other implementations of {@link Type}). + * + * @return Object of type constructed from this scopes independent values using protocol for given class or null if there was no protocol found in this {@link Serializer#getProtocols()}! + * + * @throws Exception | Exception if Exception occurred in {@link SerializationProtocol#unserialize(Class, Object...)}! + * + * @since 1.2.5 + */ + @Override + public T toObject(Type objClass) throws Exception + { + return toObject(objClass, getProtocols()); + } + + @SuppressWarnings("unchecked") + @Override + public GenericScope transform(Function trans, boolean includeSubScopes) + { + Serializer transformed = (Serializer) super.transform(trans, includeSubScopes); + transformed.parsers = getParsers(); + transformed.protocols = getProtocols(); + return (GenericScope) transformed; + } + + /** + * @see Serializer#into(Object, Serializer, String...) + */ + @Override + public T into(T obj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return Serializer.into(obj, this, fieldNamesToUse); + } + + /** + * @deprecated (1.3.9) DO NOT USE THIS, USE VARIATION OF {@link AbstractMap.SimpleEntry} OR {@link VariableConverter#NewVariable(String, Object)} FROM serialx-juss module INSTEAD! + * + * @param name | Name of variable. + * @param value | Value of variable. + * + * @return Classic variable expression in general form like [name] = [value]. + * + * @since 1.1.5 + */ + @Deprecated + public String Var(String name, T value) + { + return Code(name + " = " + getParsers().toString(value, 0, 0, this, getProtocols(), false) + ";"); + } + + /** + * @param comment | The comment... + * + * @return Comment in general form, such as //comment
Each line will be taken as new comment! + * + * @since 1.1.5 + */ + public String Comment(String comment) + { + StringBuilder sb = new StringBuilder(); + String[] lines = comment.split("\n"); + for (int i = 0; i < lines.length; i++) + sb.append("//" + lines[i] + (i < lines.length - 1 ? "\n" : "")); + return Code(sb); + } + + /** + * + * @param code | Code to convert into JUSS (StringConverter) code form. + * @return "${" + code + "} + *

Note: This works only in combination with {@link StringConverter}! + * + * @since 1.1.5 + * + * @see StringConverter#DirectCode(Object) + */ + public String Code(Object code) + { + return StringConverter.DirectCode(code); + } + + /** + * @param serialize | If true, this scope will be serialized to string! + * + * @return This scope as string! + * + * @since 1.3.2 + * + * @see Serializer#stringify(Object...) + */ + public String toString(boolean serialize) + { + if (serialize) + return stringify(); + return super.toString(); + } + + /** + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @throws Exception When creating the new instance fails... + * + * @since 1.3.2 + */ + public Serializer emptyClone() throws Exception + { + return emptyClone(this); + } + + /** + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @throws Exception When creating the new instance fails... + * + * @since 1.3.2 + */ + public Serializer emptyClone(Scope parent) throws Exception + { + return emptyClone(getClass(), parent); + } + + /** + * @param typeOfClone | Specific type of the clone (has to extend Serializer). + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @throws Exception When creating the new instance fails... + * + * @since 1.3.5 + */ + public T emptyClone(Class typeOfClone, GenericScope parent) throws Exception + { + return emptyClone(Instantiate(typeOfClone), parent); + } + + /** + * @param newEmptyInstance | Manually inserted brand new empty instance of this scope! + * @param parent | Parent scope of new Serializer instance! + * + * @return Clone of this {@link Serializer} without variables and values, protocols and parser will remain same! + * + * @since 1.3.5 + */ + public T emptyClone(T newEmptyInstance, GenericScope parent) + { + newEmptyInstance.setParsers(getParsers()); + newEmptyInstance.setProtocols(getProtocols()); + newEmptyInstance.setFormat(getFormat()); + newEmptyInstance.parent = parent; + return newEmptyInstance; + } + + @Override + public Scope clone() + { + Scope scope = super.clone(); + if (scope instanceof Serializer) + { + ((Serializer) scope).setParsers(getParsers()); + ((Serializer) scope).setProtocols(getProtocols()); + ((Serializer) scope).setFormat(getFormat()); + } + return scope; + } + + /** + * @return {@link Registry} with parsers that this {@link Serializer} uses! + * + * @since 1.3.2 + */ + public ParserRegistry getParsers() + { + if (parsers == null) + parsers = COMMON_PARSERS.clone(); + return parsers; + } + + /** + * @param parsers | Registry with parsers to set! + * + * @since 1.3.2 + */ + public void setParsers(Registry parsers) + { + setParsers(parsers instanceof ParserRegistry ? (ParserRegistry) parsers : new ParserRegistry(parsers)); + } + + /** + * @param parsers | Registry with parsers to set! + * + * @since 1.3.5 + */ + public void setParsers(ParserRegistry parsers) + { + this.parsers = (ParserRegistry) parsers; + } + + /** + * @return {@link ProtocolRegistry} with serialization protocols that this {@link Serializer} uses! + * + * @since 1.3.2 + */ + public ProtocolRegistry getProtocols() + { + if (protocols == null) + protocols = SerializationProtocol.REGISTRY.clone(); + return protocols; + } + + /** + * @param protocols | ProtocolRegistry with serialization protocols to set! + * + * @since 1.3.2 + */ + public void setProtocols(ProtocolRegistry protocols) + { + this.protocols = protocols; + } + + /** + * @param parser | DataParser to add! + * + * @return DataParser if was added! + * + * @since 1.3.2 + */ + public DataParser addParser(DataParser parser) + { + if (getParsers().add(parser)) + return parser; + return null; + } + + /** + * @param protocol | SerializationProtocol to add! + * + * @return SerializationProtocol if was added! + * + * @since 1.3.2 + */ + public SerializationProtocol addProtocol(SerializationProtocol protocol) + { + if (getProtocols().add(protocol)) + return protocol; + return null; + } + + /** + * This will transform this Serializer and whole tree of its sub-scopes into regular {@link Scope}s! + * Remember that scope is just a data container and analyzer and it can't be serialized in contrast to serializer! + * + * @return This serializer transformed in to simple {@link Scope}! + * + * @since 1.3.2 + */ + public GenericScope transformToScope() + { + Function transFunction = new Function() + { + @Override + public Object apply(Object t) + { + if (t instanceof Serializer) + { + GenericScope srl = ((Scope) t).transform(this); + return new Scope(srl.variables(), srl.values(), srl.getParent()); + } + return t; + } + }; + return (GenericScope) transform(transFunction); + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param wrappingBrackets | Array of 2 characters to wrap content inside + * @param args | Additional arguments to use, exact usage and behavior of them is based on specific implementation of this function (they should not be serialized)! + * + * @return Serialized content of this scope as inner sub-scope of this scope! Wrapped inside of corresponding wrappingBrackets (default { and })! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public
A serializeAsSubscope(A source, final char[] wrappingBrackets, Object... args) throws IOException + { + source.append(wrappingBrackets[0]); + if (isEmpty()) + return (A) source.append(wrappingBrackets[1]); + + if (format == 0) // No format... + { + if (args.length > 1 && args[1] instanceof Integer) + args[1] = ((int) args[1]) + 1; + return (A) serializeTo(source, args).append(wrappingBrackets[1]); + } + + int tabs; + if (args.length > 1 && args[1] instanceof Integer) + args[1] = (tabs = (int) args[1]) + 1; + else + tabs = 0; + + return (A) serializeTo(source.append('\n'), args).append('\n').append(multilpy('\t', tabs)) + .append(wrappingBrackets[1]); + } + + /** + * @param indexWithStringValue | Index of independent value that should be string. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from string at given index, using parsers of this {@link Serializer}! + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public T getParsed(int indexWithStringValue, Object... args) + { + return (T) getParsers().parse(getString(indexWithStringValue), args); + } + + /** + * @param variableWithStringValue | Variable name with string value. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from value of given variable, using parsers of this {@link Serializer}! + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public T getParsed(String variableWithStringValue, Object... args) + { + return (T) getParsers().parse(getString(variableWithStringValue), args); + } + + /** + * @return Non 0 value if proper indentation and newline characters should be used when serializing. Default is 0, no formating... + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} + * + * @since 1.3.9 + */ + public byte getFormat() + { + return format; + } + + /** + * @param format | A non 0 value if proper indentation and newline characters should be used when serializing. + * The exact behavior of other values will depend on the specific implementation of {@link Serializer#serializeTo(Appendable, Object...)} + * + * @since 1.3.9 + */ + public void setFormat(byte format) + { + this.format = format; + } + + /** + * @param obj | Object to map the serializer variables into! + * @param fromSerializer | Source serializer to map obj from! + * @param fieldNamesToUse | Array of obj field names to map/populate from scopes variables using setters (write method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return Same obj after being populated/mapped by contents of fromSerializer via requested fields (fieldNamesToUse) and conversion rules listed below! + * Table of specific Serializer --> Object conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (obj) typeAction with obj
{@link File}{@link Serializer#serializeTo(File, Object...)}
{@link Appendable}{@link Serializer#serializeTo(Appendable, Object...)}
{@link OutputStream}{@link Serializer#serializeTo(OutputStream, Object...)}
{@link URL}Serializer (fromSerializer) will open connection with {@link URL} and attempt serialize its content to it if possible!
{@link URLConnection}Serializer (fromSerializer) will attempt serialize its content into given {@link URLConnection} if possible!
{@link CharSequence} (as http address)Serializer (fromSerializer) will open connection with url and get + serialize the content into it if possible!
Others (default){@link Scope#into(Object, GenericScope, String...)} (return description)
+ + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during serialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static T into(Object obj, Serializer fromSerializer, String... fieldNamesToUse) throws Exception, IntrospectionException + { + if (obj instanceof File) + { + fromSerializer.serializeTo((File) obj); + return (T) obj; + } + + if (obj instanceof Appendable) + { + fromSerializer.serializeTo((Appendable) obj); + return (T) obj; + } + + if (obj instanceof OutputStream) + { + fromSerializer.serializeTo((OutputStream) obj); + return (T) obj; + } + + if (obj instanceof URL) + { + URLConnection con = ((URL) obj).openConnection(); + con.setDoOutput(true); + if (con instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) con); + else + fromSerializer.serializeTo(con.getOutputStream()); + return (T) con; + } + + if (obj instanceof URLConnection) + { + if (obj instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) obj); + else + fromSerializer.serializeTo(((URLConnection) obj).getOutputStream()); + return (T) obj; + } + + try + { + if (obj instanceof CharSequence) + { + if (indexOfNotInObj((CharSequence) obj, "http") == 0) + { + URLConnection con = new URI(obj.toString()).toURL().openConnection(); + con.setDoOutput(true); + if (con instanceof HttpURLConnection) + post(fromSerializer, (HttpURLConnection) con); + else + fromSerializer.serializeTo(con.getOutputStream()); + return (T) con; + } + + try + { + File file = new File(obj.toString()); + fromSerializer.serializeTo(file); + return (T) file; + } + catch (Exception e) + {} + } + } + catch (IOException e) + {} + + return (T) Scope.into(obj, fromSerializer, fieldNamesToUse); + } + + /** + * @param newInstance | New instance of specific {@link Serializer} + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link Serializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> Serializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went very wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * @throws RuntimeException in case of something went wrong during deserialization process and {@link LogProvider#isReThrowException()} is set to true! + * + * @since 1.3.5 + */ + public static Serializer from(Serializer newInstance, Object fromObj, String... fieldNamesToUse) throws Exception, IntrospectionException + { + if (fromObj instanceof CharSequence) + { + try + { + String fromStr; + if (indexOfNotInObj(fromStr = fromObj.toString(), "http") == 0) + return newInstance.loadFrom(new URI(fromStr).toURL().openStream()); + return newInstance.loadFrom(new File(fromStr)); + } + catch (Exception e) + { + if (e instanceof RuntimeException) + throw e; + } + + return newInstance.loadFrom((CharSequence) fromObj); + } + + if (fromObj instanceof File) + return newInstance.loadFrom((File) fromObj); + if (fromObj instanceof Reader) + return newInstance.loadFrom((Reader) fromObj); + if (fromObj instanceof InputStream) + return newInstance.loadFrom((InputStream) fromObj); + if (fromObj instanceof URL) + return newInstance.loadFrom(((URL) fromObj).openStream()); + if (fromObj instanceof URLConnection) + return newInstance.loadFrom(((URLConnection) fromObj).getInputStream()); + + newInstance.addAll(Scope.from(fromObj, fieldNamesToUse)); + return newInstance; + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index be2ba92..1d77755 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -1,117 +1,117 @@ -package org.ugp.serialx.converters; - -import static java.lang.Boolean.*; -import static org.ugp.serialx.utils.Utils.equalsLowerCase; - -import java.io.IOException; - -/** - * This converter is capable of converting {@link String}. - * Its case insensitive! - *
- *
- * Table of all string <--> object conversions: - - - - - - - - - - - - - - - - - - - - - - -
StringObject
trueBoolean.TRUE
tBoolean.TRUE
falseBoolean.FALSE
fBoolean.FALSE
- - * @author PETO - * - * @since 1.3.0 - */ -public class BooleanConverter implements DataConverter -{ - protected boolean shorten; - - public BooleanConverter() - { - this(true); - } - - /** - * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... - * - * @since 1.3.5 - */ - public BooleanConverter(boolean shorten) - { - setShorten(shorten); - } - - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len, ch0; - if ((len = str.length()) > 0) - { - if ((ch0 = str.charAt(0) | ' ') == 't' && (len == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4))) - return TRUE; - if (ch0 == 'f' && (len == 1 || len == 5 && equalsLowerCase(str, "false", 1, 5))) - return FALSE; - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Boolean) - { - if (isShorten()) - return source.append((boolean) obj ? 'T' : 'F'); - return source.append((boolean) obj ? "true" : "false"); - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); - } - - /** - * @return If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... - * - * @since 1.3.5 - */ - public boolean isShorten() - { - return shorten; - } - - /** - * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... - * - * @since 1.3.5 - */ - public void setShorten(boolean shorten) - { - this.shorten = shorten; - } -} +package org.ugp.serialx.converters; + +import static java.lang.Boolean.*; +import static org.ugp.serialx.utils.Utils.equalsLowerCase; + +import java.io.IOException; + +/** + * This converter is capable of converting {@link String}. + * Its case insensitive! + *
+ *
+ * Table of all string <--> object conversions: + + + + + + + + + + + + + + + + + + + + + + +
StringObject
trueBoolean.TRUE
tBoolean.TRUE
falseBoolean.FALSE
fBoolean.FALSE
+ + * @author PETO + * + * @since 1.3.0 + */ +public class BooleanConverter implements DataConverter +{ + protected boolean shorten; + + public BooleanConverter() + { + this(true); + } + + /** + * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ + public BooleanConverter(boolean shorten) + { + setShorten(shorten); + } + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len, ch0; + if ((len = str.length()) > 0) + { + if ((ch0 = str.charAt(0) | ' ') == 't' && (len == 1 || len == 4 && equalsLowerCase(str, "true", 1, 4))) + return TRUE; + if (ch0 == 'f' && (len == 1 || len == 5 && equalsLowerCase(str, "false", 1, 5))) + return FALSE; + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Boolean) + { + if (isShorten()) + return source.append((boolean) obj ? 'T' : 'F'); + return source.append((boolean) obj ? "true" : "false"); + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } + + /** + * @return If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ + public boolean isShorten() + { + return shorten; + } + + /** + * @param shorten | If true, shortened format (T/F) will be serialized. If false, true/false will be serialized... + * + * @since 1.3.5 + */ + public void setShorten(boolean shorten) + { + this.shorten = shorten; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java index 35bfcfb..ec1ba6c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/CharacterConverter.java @@ -1,69 +1,69 @@ -package org.ugp.serialx.converters; - -import java.io.IOException; - -/** - * This converter is capable of converting {@link Character}. - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - - - - - - - - - - - - - - -
StringObject
'a'new Character('a')
'35'new Character('#')
- * - * @author PETO - * - * @since 1.3.0 - */ -public class CharacterConverter implements DataConverter -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len; - if ((len = str.length()) > 1 && str.charAt(0) == '\'' && str.charAt(--len) == '\'') - try - { - if (len == 1) // str == "''" - return ' '; - return (char) Integer.parseInt(str.substring(1, len)); - } - catch (Exception e) - { - return str.charAt(1); - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Character) - return source.append("'"+(int) (char) obj+"'"); - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); - } -} +package org.ugp.serialx.converters; + +import java.io.IOException; + +/** + * This converter is capable of converting {@link Character}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
'a'new Character('a')
'35'new Character('#')
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class CharacterConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len; + if ((len = str.length()) > 1 && str.charAt(0) == '\'' && str.charAt(--len) == '\'') + try + { + if (len == 1) // str == "''" + return ' '; + return (char) Integer.parseInt(str.substring(1, len)); + } + catch (Exception e) + { + return str.charAt(1); + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Character) + return source.append("'"+(int) (char) obj+"'"); + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java index ff9bf24..70e1f35 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataConverter.java @@ -1,94 +1,94 @@ -package org.ugp.serialx.converters; - -import java.io.IOException; - -/** - * This is DataParser with extended functionality! {@link DataConverter} can also parse data like DataParser but is also capable of converting them back to string! - * This to string convertation is performed by {@link DataConverter#toString(Object)} and result of this convertation supposed to be parsable by {@link DataConverter#parse(String, Object...)} meaning one converter supposed to be parsing and converting via the same string format! - * - * @see DataParser - * - * @author PETO - * - * @since 1.3.0 - */ -public interface DataConverter extends DataParser -{ - /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param obj | Object to convert into string! - * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! - * - * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. - *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! - * - * @since 1.3.0 - */ - default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) - { - try - { - return (CharSequence) toString(new StringBuilder(), myHomeRegistry, obj, args); - } - catch (IOException e) - { - throw new RuntimeException(e); // Rare... - } - } - - /** - * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param obj | Object to convert into string! - * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! - * - * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. - *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! - *
Note: It is highly discouraged to append into this return! - * - * @throws IOException When appending into source throws it... - * - * @since 1.3.9 - */ - Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException; - - /** - * @param myHomeRegistry | Registry of parsers (might be null)! - * @param objToDescribe | Object to generate description for! - * @param argsUsedConvert | Array of arguments that were used for converting described object! - * - * @return Description for object (should not contain endlines)! - * - * @since 1.3.0 - */ - default CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) - { - return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + this; - } - - /** - * @param obj | Object to convert into string! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return Object converted to string using {@link DataConverter} suitable converter picked from {@link DataParser#REGISTRY}! - * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! - * - * @since 1.3.0 - */ - public static CharSequence objToString(Object obj, Object... args) - { - return REGISTRY.toString(obj, args); - } - - /** - * @param objToDescribe | Object to gen. comment for... - * - * @return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataParser.class.getName() - * - * @since 1.3.2 - */ - public static String getDefaultDescriptionFor(Object objToDescribe) - { - return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataConverter.class.getName(); - } -} +package org.ugp.serialx.converters; + +import java.io.IOException; + +/** + * This is DataParser with extended functionality! {@link DataConverter} can also parse data like DataParser but is also capable of converting them back to string! + * This to string convertation is performed by {@link DataConverter#toString(Object)} and result of this convertation supposed to be parsable by {@link DataConverter#parse(String, Object...)} meaning one converter supposed to be parsing and converting via the same string format! + * + * @see DataParser + * + * @author PETO + * + * @since 1.3.0 + */ +public interface DataConverter extends DataParser +{ + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return Object converted to string. Easiest way to do this is obj.toString() but you most likely want some more sofisticated formating. + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + * + * @since 1.3.0 + */ + default CharSequence toString(ParserRegistry myHomeRegistry, Object obj, Object... args) + { + try + { + return (CharSequence) toString(new StringBuilder(), myHomeRegistry, obj, args); + } + catch (IOException e) + { + throw new RuntimeException(e); // Rare... + } + } + + /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Note: It is highly discouraged to append into this return! + * + * @throws IOException When appending into source throws it... + * + * @since 1.3.9 + */ + Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException; + + /** + * @param myHomeRegistry | Registry of parsers (might be null)! + * @param objToDescribe | Object to generate description for! + * @param argsUsedConvert | Array of arguments that were used for converting described object! + * + * @return Description for object (should not contain endlines)! + * + * @since 1.3.0 + */ + default CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + this; + } + + /** + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Object converted to string using {@link DataConverter} suitable converter picked from {@link DataParser#REGISTRY}! + * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! + * + * @since 1.3.0 + */ + public static CharSequence objToString(Object obj, Object... args) + { + return REGISTRY.toString(obj, args); + } + + /** + * @param objToDescribe | Object to gen. comment for... + * + * @return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataParser.class.getName() + * + * @since 1.3.2 + */ + public static String getDefaultDescriptionFor(Object objToDescribe) + { + return "Object of " + objToDescribe.getClass().getName() + ": \"" + objToDescribe + "\" converted by " + DataConverter.class.getName(); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java index 07ddca4..c2870ba 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/DataParser.java @@ -1,409 +1,409 @@ -package org.ugp.serialx.converters; - -import java.io.IOException; -import java.util.Collection; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Registry; - -/** - * This interface is supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! - * Instance of DataParser should be registered into {@link DataParser#REGISTRY} or other external registry in order to work, also only one instance of each DataParser should be used and accessed via this registry!
- * Static method {@link DataParser#parseObj} is used to walk this registry and parse inserted string in process, in other words we can say that this interface contains
recursive descent parse that uses its own implementations! - * - * @author PETO - * - * @since 1.3.0 - */ -public interface DataParser -{ - /** - * This is the way how {@link DataParser} represents void. You can return this in {@link DataParser#parse(String, Object...)} as a void. - * This can be useful when you are adding something to "storage" while parsing and you do not want it to be returned. - * - * @since 1.2.2 (moved to {@link DataParser} since 1.3.0) - * - * @see Void#TYPE - */ - public static final Object VOID = Void.TYPE; - - /** - * This is connected with {@link DataParser#parse(String, Object...)} and {@link DataParser#parseObj(String, Object...)}! And its a way to tell that this parser is not suitable for parsing obtained string and search for optimal one should continue. - * Should not be modified under any circumstances, always treat as immutable! - * - * @since 1.3.0 - */ - public static final Appendable CONTINUE = new StringBuilder(0); - - /** - * This is DataParser registry. Here your parser implementations should be registered in order to work properly! - * Only one parser should be usable for specific input string, otherwise order of registration is crucial! - * Defaultly there are parsers from ugp.org.SerialX.converters. - * - * @since 1.3.0 - */ - public static final ParserRegistry REGISTRY = new ParserRegistry(new VariableParser(), new StringConverter(), new ProtocolConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); - - /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param str | Source string, preferably trimed! - * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! - * - * @return Object that was parsed from obtained string. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. - * - * @since 1.3.0 - */ - Object parse(ParserRegistry myHomeRegistry, String str, Object... args); - - /** - * @param str | Source string to parse using suitable parser from registry. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate {@link DataParser#REGISTRY} and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. - * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! - * - * @since 1.3.0 - */ - public static Object parseObj(String str, Object... args) - { - return REGISTRY.parse(str, args); - } - - /** - * Registry to store {@link DataParser} and {@link DataConverter} and performing parsing (String -> Object) and converting (Object -> String) operations with them! - * - * @author PETO - * - * @since 1.3.5 - */ - public static class ParserRegistry extends Registry implements DataConverter - { - private static final long serialVersionUID = -2598324826689380752L; - - protected DataParser[] parsingCache; - protected DataConverter[] convertingCache; - - /** - * Constructs an {@link ParserRegistry} with the specified initial capacity. - * - * @param initialSize | Initial capacity. - * - * @since 1.3.5 - */ - public ParserRegistry(int initialSize) - { - super(initialSize); - } - - /** - * Constructs an {@link ParserRegistry} with content of c. - * - * @param c | Initial content of registry. - * - * @since 1.3.5 - */ - public ParserRegistry(Collection c) - { - super(c); - } - - /** - * Constructs an {@link ParserRegistry} with parsers. - * - * @param parsers | Initial content of registry. - * - * @since 1.3.5 - */ - public ParserRegistry(DataParser... parsers) - { - super(parsers); - } - - @Override - public ParserRegistry clone() - { - return new ParserRegistry(this); - } - - /** - * @param str | String to find parser for! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Parser suitable for parsing required string, selected from inserted registry! - * - * @since 1.3.5 - */ - public DataParser getParserFor(String str, Object... args) - { - for (DataParser parser : this) - if (parser.parse(this, str, args) != CONTINUE) - return parser; - return null; - } - - /** - * @param obj | Object to find converter for! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return Converter suitable for converting required obj to string, selected from registry! - * - * @since 1.3.5 - */ - public DataConverter getConverterFor(Object obj, Object... args) - { - for (DataParser parser : this) - if (parser instanceof DataConverter && ((DataConverter) parser).toString(this, obj, args) != CONTINUE) - return (DataConverter) parser; - return null; - } - - /** - * @param obj | Object to convert into string! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return Object converted to string using {@link DataConverter} suitable converter picked from registry! - * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! - * - * @since 1.3.5 - */ - public CharSequence toString(Object obj, Object... args) - { - try - { - return (CharSequence) toString(new StringBuilder(), this, obj, args); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - /** - * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! - * @param obj | Object to convert into string! - * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! - * - * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. - *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! - *
Note: It is highly discouraged to append into this return! - * - * @throws IOException When appending into source throws it... - * - * @since 1.3.9 - */ - public Appendable toString(Appendable source, Object obj, Object... args) throws IOException - { - return toString(source, this, obj, args); - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - Appendable str; - if (convertingCache != null) - for (DataConverter parser : convertingCache) - if (parser != null && (str = parser.toString(source, myHomeRegistry, obj, args)) != CONTINUE) - return str; - - for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (myHomeRegistry == parser) // Registry is registered in itself, infinite recursion = not good skip - continue; - - if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, myHomeRegistry, obj, args)) != CONTINUE) - { - if (convertingCache != null && i < convertingCache.length) - convertingCache[i] = (DataConverter) parser; - return str; - } - } - - LogProvider.instance.logErr("Unable to convert \"" + (obj == null ? "null" : obj.getClass().getName()) + "\" to string because none of registered converters were aplicable for this object!", null); - return source.append("null"); - } - - /** - * @param parentRegistry | Registry provided by caller, but remember that {@link Registry} is also a {@link DataParser} and therefore this registry will be used instead of this argument. - * @param str | Source string to parse using suitable parser from registry. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! - * If no suitable parser/result was found, {@link DataParser#CONTINUE} will be returned, as it means that this {@link Registry} was not suitable as parser!
- * Note: If this registry contains it self as parser (which should not happen) it will attempt to skip it self in order to not cause possible infinite recursion! - * - * @see DataParser#parseObj(String, Object...) - * - * @since 1.3.8 - */ - @Override - public Object parse(ParserRegistry parentRegistry, String str, Object... args) - { - Object result; - if ((result = parse(str, true, this == parentRegistry ? getClass() : null, args)) == str) - return CONTINUE; - return result; - } - - /** - * @param str | Source string to parse using suitable parser from registry. - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. - * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! - * - * @since 1.3.5 - */ - public Object parse(String str, Object... args) - { - return parse(str, false, null, args); - } - - /** - * @param str | Source string to parse using suitable parser from registry. - * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message in case of suitable parser not found! - * @param ignore | {@link DataParser} class to ignore (if not precached)! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. - * If no suitable result was found, null or inserted string will be returned based on returnAsStringIfNotFound! - * - * @since 1.3.5 - */ - public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) - { - Object obj; - if (parsingCache != null) - for (DataParser parser : parsingCache) - if (parser != null && (obj = parser.parse(this, str, args)) != CONTINUE) - return obj; - - for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (ignore != null && ignore == parser.getClass()) - continue; - - if ((obj = parser.parse(this, str, args)) != CONTINUE) - { - if (parsingCache != null && i < parsingCache.length) - parsingCache[i] = parser; - return obj; - } - } - - if (returnAsStringIfNotFound) - return str; - - LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); - return null; - } - - /** - * @param classOfParserToPrecache | Class of parser to precache! - * - * @return Int array of 2 signifying the index of where the parser was inserted in parsing cache and converting cache (index 0 = parsing cache index, index 1 = converting cache index). These 2 values should be the same. - * - * @since 1.3.5 - */ - public int[] preCache(Class classOfParserToPrecache) - { - int[] ret = {-1, -1}; - if (parsingCache == null && convertingCache == null) - return ret; - - DataParser parser = null; - int i = 0; - for (int size = size(); i < size; i++) - { - DataParser elm = get(i); - Class objCls = elm.getClass(); - if (objCls == classOfParserToPrecache) - { - parser = elm; - break; - } - } - - if (parser == null) - return ret; - if (parser == this) - LogProvider.instance.logErr("Warning: You are pre caching instance of this registry in itself, which can result in infinite recursion. Do not do this!", null); - - if (i < parsingCache.length) - { - parsingCache[i] = parser; - ret[0] = i; - } - - if (i < convertingCache.length && parser instanceof DataConverter) - { - convertingCache[i] = (DataConverter) parser; - ret[1] = i; - } - - return ret; - } - - /** - * Recreates and enables both parsing cache and converting cache! Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other!
- * Note: Doing this will destroy any existing cache (this is usually not a big problem)! - * - * @see ParserRegistry#destroyCache() - * - * @since 1.3.5 - */ - public void resetCache() - { - int size = size(); - resetCache(new DataParser[size], new DataConverter[size]); - } - - /** - * You can use this to manually set caching arrays. Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other! - * - * @param parsingCache | Array of specific parsing cache to use (it can contains some preached parsers to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! - * @param convertingCache | Array of specific converter cache to use (it can contains some preached converters to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! - * - * @since 1.3.5 - */ - public void resetCache(DataParser[] parsingCache, DataConverter[] convertingCache) - { - if (parsingCache != null) - this.parsingCache = parsingCache; - if (convertingCache != null) - this.convertingCache = convertingCache; - } - - /** - * Destroys any existing cache and stops any further caching! Use this if you are experiencing some strange behaviors! - * - * @since 1.3.5 - */ - public void destroyCache() - { - this.parsingCache = this.convertingCache = null; - } - - /** - * @return Cache array for parsing (null if caching is disabled)! - * - * @since 1.3.5 - */ - public DataParser[] getParsingCache() - { - return parsingCache; - } - - /** - * @return Cache array for converting (null if caching is disabled)! - * - * @since 1.3.5 - */ - public DataConverter[] getConverterCache() - { - return convertingCache; - } - } -} +package org.ugp.serialx.converters; + +import java.io.IOException; +import java.util.Collection; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; + +/** + * This interface is supposed to be used to parse strings back to java objects using {@link DataParser#parse(String, Object...)}! + * Instance of DataParser should be registered into {@link DataParser#REGISTRY} or other external registry in order to work, also only one instance of each DataParser should be used and accessed via this registry!
+ * Static method {@link DataParser#parseObj} is used to walk this registry and parse inserted string in process, in other words we can say that this interface contains recursive descent parse that uses its own implementations! + * + * @author PETO + * + * @since 1.3.0 + */ +public interface DataParser +{ + /** + * This is the way how {@link DataParser} represents void. You can return this in {@link DataParser#parse(String, Object...)} as a void. + * This can be useful when you are adding something to "storage" while parsing and you do not want it to be returned. + * + * @since 1.2.2 (moved to {@link DataParser} since 1.3.0) + * + * @see Void#TYPE + */ + public static final Object VOID = Void.TYPE; + + /** + * This is connected with {@link DataParser#parse(String, Object...)} and {@link DataParser#parseObj(String, Object...)}! And its a way to tell that this parser is not suitable for parsing obtained string and search for optimal one should continue. + * Should not be modified under any circumstances, always treat as immutable! + * + * @since 1.3.0 + */ + public static final Appendable CONTINUE = new StringBuilder(0); + + /** + * This is DataParser registry. Here your parser implementations should be registered in order to work properly! + * Only one parser should be usable for specific input string, otherwise order of registration is crucial! + * Defaultly there are parsers from ugp.org.SerialX.converters. + * + * @since 1.3.0 + */ + public static final ParserRegistry REGISTRY = new ParserRegistry(new VariableParser(), new StringConverter(), new ProtocolConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param str | Source string, preferably trimed! + * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. Default SerialX API implementation will provide one optional argument with {@link Scope} that value was loaded from! + * + * @return Object that was parsed from obtained string. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. + * + * @since 1.3.0 + */ + Object parse(ParserRegistry myHomeRegistry, String str, Object... args); + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate {@link DataParser#REGISTRY} and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! + * + * @since 1.3.0 + */ + public static Object parseObj(String str, Object... args) + { + return REGISTRY.parse(str, args); + } + + /** + * Registry to store {@link DataParser} and {@link DataConverter} and performing parsing (String -> Object) and converting (Object -> String) operations with them! + * + * @author PETO + * + * @since 1.3.5 + */ + public static class ParserRegistry extends Registry implements DataConverter + { + private static final long serialVersionUID = -2598324826689380752L; + + protected DataParser[] parsingCache; + protected DataConverter[] convertingCache; + + /** + * Constructs an {@link ParserRegistry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public ParserRegistry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link ParserRegistry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public ParserRegistry(Collection c) + { + super(c); + } + + /** + * Constructs an {@link ParserRegistry} with parsers. + * + * @param parsers | Initial content of registry. + * + * @since 1.3.5 + */ + public ParserRegistry(DataParser... parsers) + { + super(parsers); + } + + @Override + public ParserRegistry clone() + { + return new ParserRegistry(this); + } + + /** + * @param str | String to find parser for! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Parser suitable for parsing required string, selected from inserted registry! + * + * @since 1.3.5 + */ + public DataParser getParserFor(String str, Object... args) + { + for (DataParser parser : this) + if (parser.parse(this, str, args) != CONTINUE) + return parser; + return null; + } + + /** + * @param obj | Object to find converter for! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Converter suitable for converting required obj to string, selected from registry! + * + * @since 1.3.5 + */ + public DataConverter getConverterFor(Object obj, Object... args) + { + for (DataParser parser : this) + if (parser instanceof DataConverter && ((DataConverter) parser).toString(this, obj, args) != CONTINUE) + return (DataConverter) parser; + return null; + } + + /** + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return Object converted to string using {@link DataConverter} suitable converter picked from registry! + * {@link DataConverter#toString(Object, Object...)} of all registered converters will be called however only suitable ones should return the result, others should return {@link DataParser#CONTINUE}! + * + * @since 1.3.5 + */ + public CharSequence toString(Object obj, Object... args) + { + try + { + return (CharSequence) toString(new StringBuilder(), this, obj, args); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! + * @param obj | Object to convert into string! + * @param args | Additional arguments that will be obtained in {@link DataParser#toString(String, Object...)}! + * + * @return The source appendable after stringified object (obj) was appropriately appended into it. Alternatively you can return null to signify error or that everything necessary was already appended and no further chars should be appended immediately after this obj's stringification. + *
Return {@link DataParser#CONTINUE} to tell that this converter is not suitable for converting this object! You most likely want to do this when obtained obj is not suitable instance! + *
Note: It is highly discouraged to append into this return! + * + * @throws IOException When appending into source throws it... + * + * @since 1.3.9 + */ + public Appendable toString(Appendable source, Object obj, Object... args) throws IOException + { + return toString(source, this, obj, args); + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + Appendable str; + if (convertingCache != null) + for (DataConverter parser : convertingCache) + if (parser != null && (str = parser.toString(source, myHomeRegistry, obj, args)) != CONTINUE) + return str; + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (myHomeRegistry == parser) // Registry is registered in itself, infinite recursion = not good skip + continue; + + if (parser instanceof DataConverter && (str = ((DataConverter) parser).toString(source, myHomeRegistry, obj, args)) != CONTINUE) + { + if (convertingCache != null && i < convertingCache.length) + convertingCache[i] = (DataConverter) parser; + return str; + } + } + + LogProvider.instance.logErr("Unable to convert \"" + (obj == null ? "null" : obj.getClass().getName()) + "\" to string because none of registered converters were aplicable for this object!", null); + return source.append("null"); + } + + /** + * @param parentRegistry | Registry provided by caller, but remember that {@link Registry} is also a {@link DataParser} and therefore this registry will be used instead of this argument. + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! + * If no suitable parser/result was found, {@link DataParser#CONTINUE} will be returned, as it means that this {@link Registry} was not suitable as parser!
+ * Note: If this registry contains it self as parser (which should not happen) it will attempt to skip it self in order to not cause possible infinite recursion! + * + * @see DataParser#parseObj(String, Object...) + * + * @since 1.3.8 + */ + @Override + public Object parse(ParserRegistry parentRegistry, String str, Object... args) + { + Object result; + if ((result = parse(str, true, this == parentRegistry ? getClass() : null, args)) == str) + return CONTINUE; + return result; + } + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null will be returned and you will be notified in console (null does not necessary means invalid output since null can be proper result of parsing)! + * + * @since 1.3.5 + */ + public Object parse(String str, Object... args) + { + return parse(str, false, null, args); + } + + /** + * @param str | Source string to parse using suitable parser from registry. + * @param returnAsStringIfNotFound | If true, inserted string will be returned instead of null and error message in case of suitable parser not found! + * @param ignore | {@link DataParser} class to ignore (if not precached)! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Object that was parsed from obtained string using suitable parser. This method will iterate registry and try to parse string using each registered parser until suitable return is obtained by parse method of parser, first suitable result will be returned! You can return {@link DataParser#CONTINUE} to mark parser as not suitable for parsing obtained string. + * If no suitable result was found, null or inserted string will be returned based on returnAsStringIfNotFound! + * + * @since 1.3.5 + */ + public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) + { + Object obj; + if (parsingCache != null) + for (DataParser parser : parsingCache) + if (parser != null && (obj = parser.parse(this, str, args)) != CONTINUE) + return obj; + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (ignore != null && ignore == parser.getClass()) + continue; + + if ((obj = parser.parse(this, str, args)) != CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + return obj; + } + } + + if (returnAsStringIfNotFound) + return str; + + LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + return null; + } + + /** + * @param classOfParserToPrecache | Class of parser to precache! + * + * @return Int array of 2 signifying the index of where the parser was inserted in parsing cache and converting cache (index 0 = parsing cache index, index 1 = converting cache index). These 2 values should be the same. + * + * @since 1.3.5 + */ + public int[] preCache(Class classOfParserToPrecache) + { + int[] ret = {-1, -1}; + if (parsingCache == null && convertingCache == null) + return ret; + + DataParser parser = null; + int i = 0; + for (int size = size(); i < size; i++) + { + DataParser elm = get(i); + Class objCls = elm.getClass(); + if (objCls == classOfParserToPrecache) + { + parser = elm; + break; + } + } + + if (parser == null) + return ret; + if (parser == this) + LogProvider.instance.logErr("Warning: You are pre caching instance of this registry in itself, which can result in infinite recursion. Do not do this!", null); + + if (i < parsingCache.length) + { + parsingCache[i] = parser; + ret[0] = i; + } + + if (i < convertingCache.length && parser instanceof DataConverter) + { + convertingCache[i] = (DataConverter) parser; + ret[1] = i; + } + + return ret; + } + + /** + * Recreates and enables both parsing cache and converting cache! Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other!
+ * Note: Doing this will destroy any existing cache (this is usually not a big problem)! + * + * @see ParserRegistry#destroyCache() + * + * @since 1.3.5 + */ + public void resetCache() + { + int size = size(); + resetCache(new DataParser[size], new DataConverter[size]); + } + + /** + * You can use this to manually set caching arrays. Doing this might give you a solid performance boost when parsing or converting large amount of objects with this registry! But sometimes, this might cause some unexpected behavior especially when you have multiple parsers that are dependent on each other! + * + * @param parsingCache | Array of specific parsing cache to use (it can contains some preached parsers to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! + * @param convertingCache | Array of specific converter cache to use (it can contains some preached converters to use preferably). This array is supposed to be as long as this registry and instances and their indexes (order) in cache should be same as in this registry! + * + * @since 1.3.5 + */ + public void resetCache(DataParser[] parsingCache, DataConverter[] convertingCache) + { + if (parsingCache != null) + this.parsingCache = parsingCache; + if (convertingCache != null) + this.convertingCache = convertingCache; + } + + /** + * Destroys any existing cache and stops any further caching! Use this if you are experiencing some strange behaviors! + * + * @since 1.3.5 + */ + public void destroyCache() + { + this.parsingCache = this.convertingCache = null; + } + + /** + * @return Cache array for parsing (null if caching is disabled)! + * + * @since 1.3.5 + */ + public DataParser[] getParsingCache() + { + return parsingCache; + } + + /** + * @return Cache array for converting (null if caching is disabled)! + * + * @since 1.3.5 + */ + public DataConverter[] getConverterCache() + { + return convertingCache; + } + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index 2b7ae79..3348969 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,66 +1,66 @@ -package org.ugp.serialx.converters; - -import static org.ugp.serialx.utils.Utils.equalsLowerCase; - -import java.io.IOException; - -/** - * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. - * Its case insensitive! - *
- *
- * Table of all string <--> object conversions: - - - - - - - - - - - - - - -
StringObject
nullnull
voidDataParser.VOID
- * - * @author PETO - * - * @since 1.3.0 - */ -public class NullConverter implements DataConverter -{ - @Override - public Object parse(ParserRegistry registry, String str, Object... args) - { - if (str.length() == 4) - { - if (equalsLowerCase(str, "null", 0, 4)) - return null; - if (equalsLowerCase(str, "void", 0, 4)) - return VOID; - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj == null) - return source.append("null"); - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - return "Null, the nothing!"; - } -} +package org.ugp.serialx.converters; + +import static org.ugp.serialx.utils.Utils.equalsLowerCase; + +import java.io.IOException; + +/** + * This converter is capable of converting "nothing" otherwise known as null and {@link DataParser#VOID}. + * Its case insensitive! + *
+ *
+ * Table of all string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
nullnull
voidDataParser.VOID
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class NullConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry registry, String str, Object... args) + { + if (str.length() == 4) + { + if (equalsLowerCase(str, "null", 0, 4)) + return null; + if (equalsLowerCase(str, "void", 0, 4)) + return VOID; + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj == null) + return source.append("null"); + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return "Null, the nothing!"; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index 3442d97..c6d323f 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -1,245 +1,245 @@ -package org.ugp.serialx.converters; - -import static org.ugp.serialx.utils.Utils.contains; - -import java.io.IOException; - -/** - * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! - * Its case insensitive! - *
- *
- * Table of sample string <--> object conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
StringObject
1337new Integer(1337)
1337Lnew Long(1337)
1337Snew Short(1337)
137Ynew Byte(137)
13.37new Double(13.37)
13.37Dnew Double(13.37)
13.37Fnew Float(13.37)
- Table of sample string --> object conversions: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
0xffnew Integer(255)
0b1111new Integer(15)
0112new Integer(74)
0112new Integer(74)
10e2new Integer(10e2)
10e2new Integer(10e2)
.1e2new Double(0.1e2)
- * - * @see NumberConverter#numberOf(CharSequence, char, int, int, int) - * - * @author PETO - * - * @since 1.3.0 - */ -public class NumberConverter implements DataConverter -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) - { - int len; - if ((len = arg.length()) > 0) - { - char ch0; - if ((ch0 = arg.charAt(0)) >= '0' && ch0 <= '9' || (ch0 == '+' || ch0 == '-' || ch0 == '.') && len > 1 && arg.charAt(1) > '*') - { - Number num; - if ((num = numberOf(arg, ch0, --len, 10, 0)) != null) - return num; - } - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Number) - { - String str; - source.append(str = format((Number) obj)); - if (obj instanceof Double && !contains(str, '.')) - source.append('D'); - else if (obj instanceof Float) - source.append('F'); - else if (obj instanceof Long) - source.append('L'); - else if (obj instanceof Short) - source.append('S'); - else if (obj instanceof Byte) - source.append('Y'); - return source; - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); - } - - /** - * @param num | Number to format before converting it to string by this converter! - * - * @return Number formated to string! - * - * @since 1.3.8 - */ - public String format(Number num) - { - return num.toString(); - } - - /** - * @param str | Source char sequence with number to parse. - * @param ch0 | Should be str.charAt(0). This is to ensure that string is not null or empty and also for possible optimizations. - * @param end | Index of where to end with parsing (inclusive). If whole string is meant to be parsed, then str.length()-1, should not be greater than that! - * @param base | Base of the parsed number. Theoretically can be anything but usually should be 2, 8, 10 or 16... Note that base will be overridden by suffixes #. for 16, 0x for 16, 0b for 2 or 0 for 8 (only if not followed by .). - * @param type | Preferred datatype of of the number represented by suffixes 'S' for {@link Short}, 'Y' for {@link Byte}, 'L' for {@link Long}, 'D' for {@link Double}, 'F' for {@link Float}. Other stands for {@link Integer}.
- * Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!
- * Important thing to know is that this argument will be overridden by suffix from str if present! - * - * @return {@link Number} parsed from str with rules specified above. This function was designed to act as more optimized merger of {@link Byte#valueOf(String, int)}, {@link Short#valueOf(String, int)}, {@link Integer#valueOf(String, int)}, {@link Long#valueOf(String, int)} and {@link Float#valueOf(String)}, {@link Double#valueOf(String)} all encapsulated in 1 universal function.
- * Note: This function will not check for incorrect number formats in order to save performance. Only incorrect format is when inserted string contains space, in this case it will return null! - * - * @since 1.3.8 - */ - public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) - { - int start = 0; - - if (ch0 == '#') //Determine base - { - base = 16; - start++; - } - else if (ch0 == '0' && end > 0) - { - int ch1 = str.charAt(1) | ' '; - if (ch1 == 'b') - { - base = 2; - start++; - } - else if (ch1 == 'x') - { - base = 16; - start++; - } - else if (ch1 != '.') - base = 8; - - start++; - } - - double result = 0, baseCof = 1, exponent = 1; - int chEnd = str.charAt(end--) | ' '; //Determine data type - if (base == 10 ? chEnd >= 'd' : chEnd >= 'l') - type = chEnd; - else if (chEnd == '.') - type = 'd'; - else - { - result = chEnd > '9' ? chEnd - 'a' + 10 : chEnd - '0'; - baseCof = base; - } - - for (int ch; end >= start; end--) //Parsing - { - if ((ch = str.charAt(end)) == '-') // Neg - result = -result; - else if (ch == '.') //Decimal - { - result /= baseCof; - baseCof = 1; - if (type == 0) - type = 'd'; - } - else if ((ch |= ' ') == 'e' && base == 10) //Handle E-notation - { - if ((exponent = Math.pow(base, result)) < 1 && type == 0) - type = 'd'; - result = 0; - baseCof = 1; - } - else if (ch == ' ') //Not valid - return null; - else if (ch != 127 && ch != '+') - { - result += (ch > '9' ? ch - 'a' + 10 : ch - '0') * baseCof; - baseCof *= base; - } - } - - result *= exponent; - - if (type == 'd') - return result; - if (type == 'f') - return (float) result; - if (type == 'l' || result > 0x7fffffff || result < 0x80000000) - return (long) result; - if (type == 's') - return (short) result; - if (type == 'y') - return (byte) result; - return (int) result; - } -} +package org.ugp.serialx.converters; + +import static org.ugp.serialx.utils.Utils.contains; + +import java.io.IOException; + +/** + * This converter is capable of converting {@link Number} including all common implementations like {@link Double}, {@link Float}, {@link Integer} and others. They are determine by suffixes like in java! + * Its case insensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
StringObject
1337new Integer(1337)
1337Lnew Long(1337)
1337Snew Short(1337)
137Ynew Byte(137)
13.37new Double(13.37)
13.37Dnew Double(13.37)
13.37Fnew Float(13.37)
+ Table of sample string --> object conversions: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
0xffnew Integer(255)
0b1111new Integer(15)
0112new Integer(74)
0112new Integer(74)
10e2new Integer(10e2)
10e2new Integer(10e2)
.1e2new Double(0.1e2)
+ * + * @see NumberConverter#numberOf(CharSequence, char, int, int, int) + * + * @author PETO + * + * @since 1.3.0 + */ +public class NumberConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + int len; + if ((len = arg.length()) > 0) + { + char ch0; + if ((ch0 = arg.charAt(0)) >= '0' && ch0 <= '9' || (ch0 == '+' || ch0 == '-' || ch0 == '.') && len > 1 && arg.charAt(1) > '*') + { + Number num; + if ((num = numberOf(arg, ch0, --len, 10, 0)) != null) + return num; + } + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Number) + { + String str; + source.append(str = format((Number) obj)); + if (obj instanceof Double && !contains(str, '.')) + source.append('D'); + else if (obj instanceof Float) + source.append('F'); + else if (obj instanceof Long) + source.append('L'); + else if (obj instanceof Short) + source.append('S'); + else if (obj instanceof Byte) + source.append('Y'); + return source; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder().append("Primitive data type: \"").append(obj).append("\" the ").append(obj.getClass().getSimpleName().toLowerCase()).append(" value!"); + } + + /** + * @param num | Number to format before converting it to string by this converter! + * + * @return Number formated to string! + * + * @since 1.3.8 + */ + public String format(Number num) + { + return num.toString(); + } + + /** + * @param str | Source char sequence with number to parse. + * @param ch0 | Should be str.charAt(0). This is to ensure that string is not null or empty and also for possible optimizations. + * @param end | Index of where to end with parsing (inclusive). If whole string is meant to be parsed, then str.length()-1, should not be greater than that! + * @param base | Base of the parsed number. Theoretically can be anything but usually should be 2, 8, 10 or 16... Note that base will be overridden by suffixes #. for 16, 0x for 16, 0b for 2 or 0 for 8 (only if not followed by .). + * @param type | Preferred datatype of of the number represented by suffixes 'S' for {@link Short}, 'Y' for {@link Byte}, 'L' for {@link Long}, 'D' for {@link Double}, 'F' for {@link Float}. Other stands for {@link Integer}.
+ * Note that floating point numberer will be treated as {@link Double} if no suffix is present by default. Also numbers in E-notation format with negative exponents can be converted to {@link Double}. Further more, integers will be auto-converted to {@link Long} if overflow should occur!
+ * Important thing to know is that this argument will be overridden by suffix from str if present! + * + * @return {@link Number} parsed from str with rules specified above. This function was designed to act as more optimized merger of {@link Byte#valueOf(String, int)}, {@link Short#valueOf(String, int)}, {@link Integer#valueOf(String, int)}, {@link Long#valueOf(String, int)} and {@link Float#valueOf(String)}, {@link Double#valueOf(String)} all encapsulated in 1 universal function.
+ * Note: This function will not check for incorrect number formats in order to save performance. Only incorrect format is when inserted string contains space, in this case it will return null! + * + * @since 1.3.8 + */ + public static Number numberOf(CharSequence str, char ch0, int end, int base, int type) + { + int start = 0; + + if (ch0 == '#') //Determine base + { + base = 16; + start++; + } + else if (ch0 == '0' && end > 0) + { + int ch1 = str.charAt(1) | ' '; + if (ch1 == 'b') + { + base = 2; + start++; + } + else if (ch1 == 'x') + { + base = 16; + start++; + } + else if (ch1 != '.') + base = 8; + + start++; + } + + double result = 0, baseCof = 1, exponent = 1; + int chEnd = str.charAt(end--) | ' '; //Determine data type + if (base == 10 ? chEnd >= 'd' : chEnd >= 'l') + type = chEnd; + else if (chEnd == '.') + type = 'd'; + else + { + result = chEnd > '9' ? chEnd - 'a' + 10 : chEnd - '0'; + baseCof = base; + } + + for (int ch; end >= start; end--) //Parsing + { + if ((ch = str.charAt(end)) == '-') // Neg + result = -result; + else if (ch == '.') //Decimal + { + result /= baseCof; + baseCof = 1; + if (type == 0) + type = 'd'; + } + else if ((ch |= ' ') == 'e' && base == 10) //Handle E-notation + { + if ((exponent = Math.pow(base, result)) < 1 && type == 0) + type = 'd'; + result = 0; + baseCof = 1; + } + else if (ch == ' ') //Not valid + return null; + else if (ch != 127 && ch != '+') + { + result += (ch > '9' ? ch - 'a' + 10 : ch - '0') * baseCof; + baseCof *= base; + } + } + + result *= exponent; + + if (type == 'd') + return result; + if (type == 'f') + return (float) result; + if (type == 'l' || result > 0x7fffffff || result < 0x80000000) + return (long) result; + if (type == 's') + return (short) result; + if (type == 'y') + return (byte) result; + return (int) result; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index defac7f..1a5619c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -1,463 +1,463 @@ -package org.ugp.serialx.converters; - -import static org.ugp.serialx.utils.Utils.*; - -import java.io.IOException; -import java.io.Serializable; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Base64; -import java.util.HashSet; -import java.util.Set; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; - -/** - * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - * - - - - - - - - - - - - - -
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
- Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
-
- This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
- This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
- * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
- * - * @author PETO - * - * @since 1.3.0 (separated from ObjectConverter since 1.3.8) - */ -public class ProtocolConverter implements DataConverter -{ - /** - * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. - * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ProtocolConverter}) - */ - protected boolean useBase64IfCan = false; - - protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, GenericScope.class, Double.class, Float.class, String.class)); - - protected long protocolType = 0; - - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) - { - int len; - if ((len = str.length()) > 0) - { - if ((str.charAt(0) | ' ') == '{' && (str.charAt(--len) | ' ') == '}') // Unwrap if wrapped in {} - str = str.substring(1, len).trim(); - - Class objClass; - if ((objClass = getProtocolExprClass(str, compilerArgs)) != null) // Get class of protocol expr or continue if there is none - return parse(myHomeRegistry, objClass, str, compilerArgs); - } - return CONTINUE; - } - - /** - * @param myHomeRegistry | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. - * @param objClass | Class of object to parse using {@link SerializationProtocol}. - * @param str | String that starts with {@link Class} of object to deserialized (it will be used with {@link SerializationProtocol#unserializeObj(ProtocolRegistry, long, Class, Object...)}). - * @param compilerArgs | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. - * - * @return Object od objClass parsed from str in accordance with compilerArgs! - * - * @since 1.3.8 - */ - protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String str, Object... compilerArgs) - { - if (objClass == IsSelectorScope.class) //Handle css-like selector scope to variable assignment - { - StringBuilder sb = new StringBuilder(str); - sb.setCharAt(str.indexOf(' '), '='); - return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ProtocolConverter and VariableConverter are present... - } - - if (compilerArgs.length < 5) - compilerArgs = Arrays.copyOf(compilerArgs, 5); - Class oldObjectClass = (Class) compilerArgs[4]; - compilerArgs[4] = objClass; - - String[] args = splitValues(str, ' '); - int nameIndex; - if ((args[0].charAt(0) | ' ') != '{' && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation - { - String memberName = args[0].substring(nameIndex + 2); - if (!getInvokableClasses().contains(objClass)) - { - LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because it was not enabled for this class for security reasons!", null); - return null; - } - - if (args.length > 1) - return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); - - try - { - compilerArgs[4] = oldObjectClass; - return memberName.equals("class") ? objClass : memberName.equals("new") ? Instantiate(objClass) : objClass.getField(memberName).get(null); - } - catch (NoSuchFieldException e) - { - return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); - } - catch (Exception e) - { - LogProvider.instance.logErr("Unable to obtain value of field \"" + memberName + "\" in class \"" + objClass.getSimpleName() + "\" because:", e); - e.printStackTrace(); - return null; - } - } - - try - { -// if ((ch = str.charAt(str.length()-1)) == ';' || ch == ',') -// throw new ClassNotFoundException(); - - Object[] objArgs = parseAll(myHomeRegistry, args, 1, true, compilerArgs); - if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objClass)) - return objArgs[0]; - compilerArgs[4] = oldObjectClass; - return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, getProtocolType(), objClass, objArgs); - } - catch (Exception e) - { - LogProvider.instance.logErr("Exception while unserializing instance of \"" + objClass.getName() + "\":", e); - e.printStackTrace(); - return null; - } - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - return toString(source, myHomeRegistry, obj, null, args); - } - - /** - * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param obj | Object to convert into string! - * @param preferedProtocol | Protocol to use preferably. - * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! - * - * @return In accordance with {@link DataConverter#toString(Appendable, org.ugp.serialx.converters.DataParser.ParserRegistry, Object, Object...)}. - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) - { - if (obj == null) - return CONTINUE; - - if (useBase64IfCan && obj instanceof Serializable) - return CONTINUE; - - if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE | getProtocolType(), args)) != null) - { - if (args.length < 6) - args = Arrays.copyOf(args, 6); - Class oldObjectClass = (Class) args[4]; - args[4] = obj.getClass(); - - int tabs = args[1] instanceof Integer ? (int) args[1] : 0; - int index = args[2] instanceof Integer ? (int) args[2] : 0; - - try - { - Object[] objArgs = preferedProtocol.serialize(obj); - final int len = objArgs.length; - - boolean wrap; - if (wrap = index > 0 && len != 0) - source.append('{'); - - source.append(ImportsProvider.getAliasFor(args[0], obj.getClass())); - args = args.clone(); - if (args[5] instanceof Byte && (byte) args[5] != 0) // Format - { - for (int i = 0; i < len; i++) - { - if (i != 0 && i % 1000 == 0) - { - source.append('\n'); - for (int j = 0; j < tabs+1; j++) - source.append('\t'); - } - else - source.append(' '); - - if (args.length > 2) - args[2] = index + 1; // DO NOT TOUCH - myHomeRegistry.toString(source, objArgs[i], args); - } - } - else - { - for (int i = 0; i < len; i++) - { - source.append(' '); - - if (args.length > 2) - args[2] = index + 1; // DO NOT TOUCH - myHomeRegistry.toString(source, objArgs[i], args); - } - } - - args[4] = oldObjectClass; - return wrap ? source.append('}') : source; - } - catch (Exception e) - { - LogProvider.instance.logErr("Exception while serializing instance of \"" + obj.getClass().getName() + "\":", e); - e.printStackTrace(); - } - args[4] = oldObjectClass; - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, ENDL) != -1) - return "Multiline char sequence!"; - return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE_DESERIALIZE | getProtocolType(), argsUsedConvert)).append("!"); - } - - /** - * @return True if program is forced to use {@link Base64} serialization on {@link Serializable} objects. - * This might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.3.5 - */ - public boolean isUseBase64IfCan() - { - return useBase64IfCan; - } - - /** - * @param useBase64IfCan | Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. - * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! - * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. - * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
- * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
- * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! - * - * @since 1.3.5 - */ - public void setUseBase64IfCan(boolean useBase64IfCan) - { - this.useBase64IfCan = useBase64IfCan; - } - - /** - * @return The additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). - * - * @since 1.3.8 - */ - public long getProtocolType() - { - return protocolType; - } - - /** - * @param protocolType | Value of additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). - * - * @since 1.3.8 - */ - public void setProtocolType(long protocolType) - { - this.protocolType = protocolType; - } - - /** - * @return Classes that are eligible for public static member invocation (:: operator)!
- * Note: {@link Math} {@link Scope} {@link Double}, {@link Float} and {@link String} are invokable by default! If you want to disable static member invocation completely, call {@link Set#clear()} on this method! - * - * @since 1.3.8 - */ - public Set> getInvokableClasses() - { - return invokableClasses; - } - - /** - * @param obj | Object to get protocol for! - * @param mode | Protocol mode! - * @param args | Parser args to get protocol from! - * - * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
- * Note: This is mainly used by {@link ProtocolConverter}! - * - * @since 1.3.5 - */ - public static SerializationProtocol getProtocolFor(Object obj, long mode, Object[] args) - { - if (args.length > 3) - { - if (args[3] instanceof ProtocolRegistry) - return ((ProtocolRegistry) args[3]).GetProtocolFor(obj, mode); - else if (args[3] instanceof SerializationProtocol) - return (SerializationProtocol) args[3]; - } - - return SerializationProtocol.REGISTRY.GetProtocolFor(obj, mode); - } - - /** - * @param str | String to check protocol class for! - * @param args | Args provided by the caller. Should contain {@link ImportsProvider}-like object at index 0. - * - * @return Class of the protocol or null if inserted statement is not protocol expression! - * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! - * - * @since 1.3.0 - */ - public static Class getProtocolExprClass(String str, Object... args) - { - int i = 0, len = str.length(); - for (char ch; i < len; i++) - if ((ch = str.charAt(i)) == ' ' || ch == ':') - break; - - try - { - Class cls = ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(0, i), false, ProtocolConverter.class.getClassLoader()); - if (cls != null) - return cls; - for (char ch; i < len; i++) - { - if ((ch = str.charAt(i)) > 32) - if ((ch | ' ') == '{') - return IsSelectorScope.class; - else - return null; - } - } - catch (ClassNotFoundException e) - {} - return null; - } - - /** - * @param registry | Registry to use! - * @param strs | Source strings to parse using suitable parser from registry. - * @param from | Start index to begin from! - * @param trim | If true, all strings will be trimed before parsing! - * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! - * - * @return Array of parsed objects, each parsed using {@link DataParser#parseObj(String, Object...)} - * - * @since 1.3.0 - */ - public static Object[] parseAll(ParserRegistry registry, String strs[], int from, boolean trim, Object... args) - { - Object[] objs = new Object[strs.length-from]; - for (int i = 0; from < strs.length; from++, i++) - objs[i] = registry.parse(trim ? strs[from].trim() : strs[from], args); - return objs; - } - - /** - * @return Array with 2 preferred sub-scope wrapping chars that are used during serialization by default. { and } - * - * @since 1.3.5 - */ - public static char[] primarySubscopeWrappers() - { - return new char[] {'{', '}'}; - } - - /** - * @return Array with 2 secondary sub-scope wrapping char. [ and ] - * - * @since 1.3.5 - */ - public static char[] secondarySubscopeWrappers() - { - return new char[] {'[', ']'}; - } - - /** - * @param cls | Class to invoke method from. - * @param oldCls | Old class to set (obtained from compilerArgs[4]). - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * @param compilerArgs | Arguments provided by parser. - * - * @return {@link Utils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
- * Note: If you are not sure what this does, preferably use {@link Utils#InvokeStaticFunc(Class, String, Object...)}! - * - * @since 1.3.8 - */ - public static Object InvokeStaticFunc(Class cls, Class oldCls, String name, Object[] args, Object... compilerArgs) { - try - { - compilerArgs[4] = oldCls; - return Utils.InvokeStaticFunc(cls, name, args); - } - catch (InvocationTargetException e) - { - LogProvider.instance.logErr("Exception while calling method \"" + name + "\":", e); - e.printStackTrace(); - return null; - } - } - - /** - * Used internally by {@link ProtocolConverter}!
- * Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: - * - * shortenedSelectorLikeScope {

- * //stuff... - * }; - *
- * - * @author PETO - * - * @since 1.3.0 - */ - protected static class IsSelectorScope {}; +package org.ugp.serialx.converters; + +import static org.ugp.serialx.utils.Utils.*; + +import java.io.IOException; +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.HashSet; +import java.util.Set; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; + +/** + * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + +
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
java.lang.Math::max 10 510
+ Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
+
+ This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
+ This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
+ * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
+ * + * @author PETO + * + * @since 1.3.0 (separated from ObjectConverter since 1.3.8) + */ +public class ProtocolConverter implements DataConverter +{ + /** + * Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0 and since 1.3.5 into {@link ProtocolConverter}) + */ + protected boolean useBase64IfCan = false; + + protected Set> invokableClasses = new HashSet<>(Arrays.asList(Math.class, GenericScope.class, Double.class, Float.class, String.class)); + + protected long protocolType = 0; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) + { + int len; + if ((len = str.length()) > 0) + { + if ((str.charAt(0) | ' ') == '{' && (str.charAt(--len) | ' ') == '}') // Unwrap if wrapped in {} + str = str.substring(1, len).trim(); + + Class objClass; + if ((objClass = getProtocolExprClass(str, compilerArgs)) != null) // Get class of protocol expr or continue if there is none + return parse(myHomeRegistry, objClass, str, compilerArgs); + } + return CONTINUE; + } + + /** + * @param myHomeRegistry | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. + * @param objClass | Class of object to parse using {@link SerializationProtocol}. + * @param str | String that starts with {@link Class} of object to deserialized (it will be used with {@link SerializationProtocol#unserializeObj(ProtocolRegistry, long, Class, Object...)}). + * @param compilerArgs | Same as {@link DataParser#parse(ParserRegistry, String, Object...)}. + * + * @return Object od objClass parsed from str in accordance with compilerArgs! + * + * @since 1.3.8 + */ + protected Object parse(ParserRegistry myHomeRegistry, Class objClass, String str, Object... compilerArgs) + { + if (objClass == IsSelectorScope.class) //Handle css-like selector scope to variable assignment + { + StringBuilder sb = new StringBuilder(str); + sb.setCharAt(str.indexOf(' '), '='); + return myHomeRegistry.parse(sb.toString(), compilerArgs); //Should work only when ProtocolConverter and VariableConverter are present... + } + + if (compilerArgs.length < 5) + compilerArgs = Arrays.copyOf(compilerArgs, 5); + Class oldObjectClass = (Class) compilerArgs[4]; + compilerArgs[4] = objClass; + + String[] args = splitValues(str, ' '); + int nameIndex; + if ((args[0].charAt(0) | ' ') != '{' && (nameIndex = args[0].indexOf("::")) > -1) //Is static member invocation + { + String memberName = args[0].substring(nameIndex + 2); + if (!getInvokableClasses().contains(objClass)) + { + LogProvider.instance.logErr("Invocation of static member \"" + memberName + "\" from class \"" + objClass.getName() + "\" was denied because it was not enabled for this class for security reasons!", null); + return null; + } + + if (args.length > 1) + return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); + + try + { + compilerArgs[4] = oldObjectClass; + return memberName.equals("class") ? objClass : memberName.equals("new") ? Instantiate(objClass) : objClass.getField(memberName).get(null); + } + catch (NoSuchFieldException e) + { + return InvokeStaticFunc(objClass, oldObjectClass, memberName, parseAll(myHomeRegistry, args, 1, true, compilerArgs), compilerArgs); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to obtain value of field \"" + memberName + "\" in class \"" + objClass.getSimpleName() + "\" because:", e); + e.printStackTrace(); + return null; + } + } + + try + { +// if ((ch = str.charAt(str.length()-1)) == ';' || ch == ',') +// throw new ClassNotFoundException(); + + Object[] objArgs = parseAll(myHomeRegistry, args, 1, true, compilerArgs); + if (objArgs.length == 1 && objArgs[0] instanceof Scope && Scope.class.isAssignableFrom(objClass)) + return objArgs[0]; + compilerArgs[4] = oldObjectClass; + return SerializationProtocol.unserializeObj(compilerArgs.length > 3 && compilerArgs[3] instanceof ProtocolRegistry ? (ProtocolRegistry) compilerArgs[3] : SerializationProtocol.REGISTRY, getProtocolType(), objClass, objArgs); + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while unserializing instance of \"" + objClass.getName() + "\":", e); + e.printStackTrace(); + return null; + } + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + return toString(source, myHomeRegistry, obj, null, args); + } + + /** + * @param source | Source to append the properly stringified object (obj) into. Should be treated as only and only {@link Appendable}, no casting! + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param obj | Object to convert into string! + * @param preferedProtocol | Protocol to use preferably. + * @param args | Some additional args. This can be anything and it demands on implementation of DataConverter. Default SerialX API implementation will provide some flags about formating (2 ints)! + * + * @return In accordance with {@link DataConverter#toString(Appendable, org.ugp.serialx.converters.DataParser.ParserRegistry, Object, Object...)}. + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) + { + if (obj == null) + return CONTINUE; + + if (useBase64IfCan && obj instanceof Serializable) + return CONTINUE; + + if (preferedProtocol != null || (preferedProtocol = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE | getProtocolType(), args)) != null) + { + if (args.length < 6) + args = Arrays.copyOf(args, 6); + Class oldObjectClass = (Class) args[4]; + args[4] = obj.getClass(); + + int tabs = args[1] instanceof Integer ? (int) args[1] : 0; + int index = args[2] instanceof Integer ? (int) args[2] : 0; + + try + { + Object[] objArgs = preferedProtocol.serialize(obj); + final int len = objArgs.length; + + boolean wrap; + if (wrap = index > 0 && len != 0) + source.append('{'); + + source.append(ImportsProvider.getAliasFor(args[0], obj.getClass())); + args = args.clone(); + if (args[5] instanceof Byte && (byte) args[5] != 0) // Format + { + for (int i = 0; i < len; i++) + { + if (i != 0 && i % 1000 == 0) + { + source.append('\n'); + for (int j = 0; j < tabs+1; j++) + source.append('\t'); + } + else + source.append(' '); + + if (args.length > 2) + args[2] = index + 1; // DO NOT TOUCH + myHomeRegistry.toString(source, objArgs[i], args); + } + } + else + { + for (int i = 0; i < len; i++) + { + source.append(' '); + + if (args.length > 2) + args[2] = index + 1; // DO NOT TOUCH + myHomeRegistry.toString(source, objArgs[i], args); + } + } + + args[4] = oldObjectClass; + return wrap ? source.append('}') : source; + } + catch (Exception e) + { + LogProvider.instance.logErr("Exception while serializing instance of \"" + obj.getClass().getName() + "\":", e); + e.printStackTrace(); + } + args[4] = oldObjectClass; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + if (obj instanceof CharSequence && indexOfNotInObj((CharSequence) obj, ENDL) != -1) + return "Multiline char sequence!"; + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\" serialized using ").append(getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE_DESERIALIZE | getProtocolType(), argsUsedConvert)).append("!"); + } + + /** + * @return True if program is forced to use {@link Base64} serialization on {@link Serializable} objects. + * This might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public boolean isUseBase64IfCan() + { + return useBase64IfCan; + } + + /** + * @param useBase64IfCan | Set this on true to force program to use {@link Base64} serialization on {@link Serializable} objects. + * Doing this might result into some form of encryption but its less flexible and tends to be slower than SerialX {@link SerializationProtocol} system! + * In some cases, java Serialization can be more effective than protocols sometimes not! You should try which gives you the best result, then you can also deactivate certain protocols that are less effective than Java serialization. + * For example for long strings, classic Java serialization is better than protocol, it will take less memory storage space, but performance is almost always far slower!
+ * Note: Whole concept of SerialX API is about avoiding classic Java serialization from many reasons so you most likely want this on true! Also protocol will be almost certainly faster classic serialization!
+ * Note: This will only work when this converter is registered in {@link ParserRegistry} together with {@link SerializableBase64Converter}! + * + * @since 1.3.5 + */ + public void setUseBase64IfCan(boolean useBase64IfCan) + { + this.useBase64IfCan = useBase64IfCan; + } + + /** + * @return The additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). + * + * @since 1.3.8 + */ + public long getProtocolType() + { + return protocolType; + } + + /** + * @param protocolType | Value of additional protocol type that will chained with {@link SerializationProtocol#MODE_SERIALIZE} and {@link SerializationProtocol#MODE_DESERIALIZE} (none (0) by default). + * + * @since 1.3.8 + */ + public void setProtocolType(long protocolType) + { + this.protocolType = protocolType; + } + + /** + * @return Classes that are eligible for public static member invocation (:: operator)!
+ * Note: {@link Math} {@link Scope} {@link Double}, {@link Float} and {@link String} are invokable by default! If you want to disable static member invocation completely, call {@link Set#clear()} on this method! + * + * @since 1.3.8 + */ + public Set> getInvokableClasses() + { + return invokableClasses; + } + + /** + * @param obj | Object to get protocol for! + * @param mode | Protocol mode! + * @param args | Parser args to get protocol from! + * + * @return Protocol obtained from args or from {@link SerializationProtocol#REGISTRY} if there is no protocol or {@link ProtocolRegistry} in args (index 3).
+ * Note: This is mainly used by {@link ProtocolConverter}! + * + * @since 1.3.5 + */ + public static SerializationProtocol getProtocolFor(Object obj, long mode, Object[] args) + { + if (args.length > 3) + { + if (args[3] instanceof ProtocolRegistry) + return ((ProtocolRegistry) args[3]).GetProtocolFor(obj, mode); + else if (args[3] instanceof SerializationProtocol) + return (SerializationProtocol) args[3]; + } + + return SerializationProtocol.REGISTRY.GetProtocolFor(obj, mode); + } + + /** + * @param str | String to check protocol class for! + * @param args | Args provided by the caller. Should contain {@link ImportsProvider}-like object at index 0. + * + * @return Class of the protocol or null if inserted statement is not protocol expression! + * For example: getProtocolExprClass("java.util.ArrayList 1 2 3 4 5") will return {@link ArrayList} but "Hello world!" will return null! + * + * @since 1.3.0 + */ + public static Class getProtocolExprClass(String str, Object... args) + { + int i = 0, len = str.length(); + for (char ch; i < len; i++) + if ((ch = str.charAt(i)) == ' ' || ch == ':') + break; + + try + { + Class cls = ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(0, i), false, ProtocolConverter.class.getClassLoader()); + if (cls != null) + return cls; + for (char ch; i < len; i++) + { + if ((ch = str.charAt(i)) > 32) + if ((ch | ' ') == '{') + return IsSelectorScope.class; + else + return null; + } + } + catch (ClassNotFoundException e) + {} + return null; + } + + /** + * @param registry | Registry to use! + * @param strs | Source strings to parse using suitable parser from registry. + * @param from | Start index to begin from! + * @param trim | If true, all strings will be trimed before parsing! + * @param args | Additional arguments that will be obtained in {@link DataParser#parse(String, Object...)}! + * + * @return Array of parsed objects, each parsed using {@link DataParser#parseObj(String, Object...)} + * + * @since 1.3.0 + */ + public static Object[] parseAll(ParserRegistry registry, String strs[], int from, boolean trim, Object... args) + { + Object[] objs = new Object[strs.length-from]; + for (int i = 0; from < strs.length; from++, i++) + objs[i] = registry.parse(trim ? strs[from].trim() : strs[from], args); + return objs; + } + + /** + * @return Array with 2 preferred sub-scope wrapping chars that are used during serialization by default. { and } + * + * @since 1.3.5 + */ + public static char[] primarySubscopeWrappers() + { + return new char[] {'{', '}'}; + } + + /** + * @return Array with 2 secondary sub-scope wrapping char. [ and ] + * + * @since 1.3.5 + */ + public static char[] secondarySubscopeWrappers() + { + return new char[] {'[', ']'}; + } + + /** + * @param cls | Class to invoke method from. + * @param oldCls | Old class to set (obtained from compilerArgs[4]). + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * @param compilerArgs | Arguments provided by parser. + * + * @return {@link Utils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
+ * Note: If you are not sure what this does, preferably use {@link Utils#InvokeStaticFunc(Class, String, Object...)}! + * + * @since 1.3.8 + */ + public static Object InvokeStaticFunc(Class cls, Class oldCls, String name, Object[] args, Object... compilerArgs) { + try + { + compilerArgs[4] = oldCls; + return Utils.InvokeStaticFunc(cls, name, args); + } + catch (InvocationTargetException e) + { + LogProvider.instance.logErr("Exception while calling method \"" + name + "\":", e); + e.printStackTrace(); + return null; + } + } + + /** + * Used internally by {@link ProtocolConverter}!
+ * Dummy class with no purpose except to be mark (.class) for shortened scope expression such as: + * + * shortenedSelectorLikeScope {

+ * //stuff... + * }; + *
+ * + * @author PETO + * + * @since 1.3.0 + */ + protected static class IsSelectorScope {}; } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java index 71fe69e..8156070 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/SerializableBase64Converter.java @@ -1,136 +1,136 @@ -package org.ugp.serialx.converters; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.net.URLDecoder; -import java.net.URLEncoder; -import java.util.Base64; - -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.LogProvider; - -/** - * This converter is capable of converting {@link Serializable}. - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - - - - - - - - - - - - - - -
StringObject
#rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAAdwQAAAAAeA#3D#3Dnew ArrayList()
#rO0ABXVyAAJbSU26YCZ26rKlAgAAeHAAAAADAAAABQAAAAUAAAAFnew int[] {5, 5, 5}
- * Note: In most of the cases {@link SerializationProtocol} and therefore {@link ProtocolConverter} should be used as preferable alternative!
- * Note: In order to avoid conflicts with JUSS syntax, this converter serializes and deserializes by using {@link Base64} and {@link URLEncoder} with addition of all % are being replaced by #! - * - * @author PETO - * - * @since 1.3.0 - */ -public class SerializableBase64Converter implements DataConverter -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) - { - if (arg.length() <= 0) - return CONTINUE; - - char ch0 = arg.charAt(0); - if (ch0 == '#' || ch0 == 'r') - { - try - { - if (ch0 == '#') - return UnserializeClassis(arg = URLDecoder.decode(arg.substring(1).replace('#', '%'), "UTF-8")); - return UnserializeClassis(arg = URLDecoder.decode(arg.replace('#', '%'), "UTF-8")); - } - catch (Exception e) - { - LogProvider.instance.logErr("Looks like there were some problems with unserializing some object, the instance of java.io.Serializable from string \"" + arg + "\"! This string is most likely corrupted! See error below:", e); - e.printStackTrace(); - return null; - } - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) - { - if (obj instanceof Serializable) - try - { - return source.append('#').append(URLEncoder.encode(SerializeClassic((Serializable) obj), "UTF-8").replace('%', '#')); - } - catch (Exception e) - { - LogProvider.instance.logErr("Looks like there were some problems with serializing \"" + obj + "\", the instance of java.io.Serializable. This could happen when certain object contains non-transient unserializable objects. Using custom valid protocol for serializing \"" + obj + "\" might solve the problem!", e); - e.printStackTrace(); - return null; - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj).append("\" serialized using classic Base64 java.io.Serializable!"); - } - - /** - * @param objStr | String to unserialize by classic Java serialization. - * - * @return Unsrialized object. - * - * @throws IOException - if an I/O error occurs while reading stream header. - * @throws ClassNotFoundException - Class of a serialized object cannot be found. - * - * @see java.util.Base64 - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) - */ - public static Object UnserializeClassis(String objStr) throws IOException, ClassNotFoundException - { - return new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(objStr))).readObject(); - } - - /** - * @param obj | Object to serialize using classic Java serialization. - * - * @return String with serialized object. - * - * @throws Exception - if an I/O error occurs while writing stream header - * - * @see java.lang.Base64 - * - * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) - */ - public static String SerializeClassic(Serializable obj) throws Exception - { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(baos); - - oos.writeObject(obj); - oos.close(); - return Base64.getEncoder().encodeToString(baos.toByteArray()); - } -} +package org.ugp.serialx.converters; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; +import java.net.URLDecoder; +import java.net.URLEncoder; +import java.util.Base64; + +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.LogProvider; + +/** + * This converter is capable of converting {@link Serializable}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + +
StringObject
#rO0ABXNyABNqYXZhLnV0aWwuQXJyYXlMaXN0eIHSHZnHYZ0DAAFJAARzaXpleHAAAAAAdwQAAAAAeA#3D#3Dnew ArrayList()
#rO0ABXVyAAJbSU26YCZ26rKlAgAAeHAAAAADAAAABQAAAAUAAAAFnew int[] {5, 5, 5}
+ * Note: In most of the cases {@link SerializationProtocol} and therefore {@link ProtocolConverter} should be used as preferable alternative!
+ * Note: In order to avoid conflicts with JUSS syntax, this converter serializes and deserializes by using {@link Base64} and {@link URLEncoder} with addition of all % are being replaced by #! + * + * @author PETO + * + * @since 1.3.0 + */ +public class SerializableBase64Converter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (arg.length() <= 0) + return CONTINUE; + + char ch0 = arg.charAt(0); + if (ch0 == '#' || ch0 == 'r') + { + try + { + if (ch0 == '#') + return UnserializeClassis(arg = URLDecoder.decode(arg.substring(1).replace('#', '%'), "UTF-8")); + return UnserializeClassis(arg = URLDecoder.decode(arg.replace('#', '%'), "UTF-8")); + } + catch (Exception e) + { + LogProvider.instance.logErr("Looks like there were some problems with unserializing some object, the instance of java.io.Serializable from string \"" + arg + "\"! This string is most likely corrupted! See error below:", e); + e.printStackTrace(); + return null; + } + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) + { + if (obj instanceof Serializable) + try + { + return source.append('#').append(URLEncoder.encode(SerializeClassic((Serializable) obj), "UTF-8").replace('%', '#')); + } + catch (Exception e) + { + LogProvider.instance.logErr("Looks like there were some problems with serializing \"" + obj + "\", the instance of java.io.Serializable. This could happen when certain object contains non-transient unserializable objects. Using custom valid protocol for serializing \"" + obj + "\" might solve the problem!", e); + e.printStackTrace(); + return null; + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + return new StringBuilder("Object of ").append(obj.getClass().getName()).append(": \"").append(obj).append("\" serialized using classic Base64 java.io.Serializable!"); + } + + /** + * @param objStr | String to unserialize by classic Java serialization. + * + * @return Unsrialized object. + * + * @throws IOException - if an I/O error occurs while reading stream header. + * @throws ClassNotFoundException - Class of a serialized object cannot be found. + * + * @see java.util.Base64 + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) + */ + public static Object UnserializeClassis(String objStr) throws IOException, ClassNotFoundException + { + return new ObjectInputStream(new ByteArrayInputStream(Base64.getDecoder().decode(objStr))).readObject(); + } + + /** + * @param obj | Object to serialize using classic Java serialization. + * + * @return String with serialized object. + * + * @throws Exception - if an I/O error occurs while writing stream header + * + * @see java.lang.Base64 + * + * @since 1.0.0 (moved to {@link SerializableBase64Converter} since 1.3.0) + */ + public static String SerializeClassic(Serializable obj) throws Exception + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + + oos.writeObject(obj); + oos.close(); + return Base64.getEncoder().encodeToString(baos.toByteArray()); + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 2985f7c..0487378 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -1,167 +1,167 @@ -package org.ugp.serialx.converters; - -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * This converter is capable of converting {@link String}. - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - - - - - - - - - - -
StringObject
"Hello world!"new String("Hello world!")
- * If you enter string in ${yourString}, "yourString" will be returned by {@link StringConverter#toString} according to {@link StringConverter#DirectCode}! - * - * @author PETO - * - * @since 1.3.0 - */ -public class StringConverter implements DataConverter -{ - /** - * Set this on true and {@link String} will be serialized normally, for instance "Hello world!" and not using protocols or java Base64!
- * Setting this on false will also make Strings unreadable for normal people! - * - * @since 1.2.0 (moved to {@link StringConverter} since 1.3.0) - */ - protected boolean serializeStringNormally = true; - - protected Map parsingCache; - - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - String result; - int len; - if ((len = str.length()) > 1 && str.charAt(0) == '\"' && str.charAt(--len) == '\"' && indexOfNotInObj(str, ' ') == -1) - { - if (parsingCache != null) - { - if ((result = parsingCache.get(str)) != null) - return result; - parsingCache.put(str, result = str.substring(1, len)); - return result; - } - return str.substring(1, len); - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof String) - { - String str = (String) obj; - if (str.startsWith("${") && str.endsWith("}")) - { - str = str.substring(2, str.length()-1); - if (str.contains("::") && indexOfNotInObj(str, ' ') > -1) - return source.append('{').append(str).append('}'); - - if (indexOfNotInObj(str, "//") != -1) - { - source.append(str); - return null; // No append ; when ends with // - } - return source.append(str); - } - - if (serializeStringNormally) - { - if (contains(str, '\"', '\n', '\r')) - return CONTINUE; - return source.append('"').append(str).append('"'); - } - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - String str = obj.toString(); - boolean hasComment = false; - if (str.startsWith("${") && str.endsWith("}") && !(hasComment = str.substring(2).contains("//"))) - return "Manually inserted code!"; - if (!hasComment) - return new StringBuilder().append("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\"!"); - return ""; - } - - /** - * @param cache | Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool. Doing this can save you some memory with minimal performance overhead!
- * Setting this to null will disable the parsing result caching by this {@link StringConverter} as it is by default.
- * Recommended: Enable this when parsing a lot of strings that are the same, otherwise this will not have a big impact.
- * Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! - * - * @since 1.3.8 - */ - public void setParsingCache(Map cache) - { - parsingCache = cache; - } - - /** - * @return Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool.
- * Null will be returned if caching is disabled, which is by default...
- * Note: Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! - * - * @since 1.3.8 - */ - public Map getParsingCache() - { - return parsingCache; - } - - /** - * @return Will return value of {@link StringConverter#serializeStringNormally}! - * - * @since 1.3.8 (it was static before = not good) - */ - public boolean isSerializeStringNormally() - { - return serializeStringNormally; - } - - /** - * @param serializeStringNormally | Set value of {@link StringConverter#serializeStringNormally}! - * - * @since 1.3.8 (it was static before = not good) - */ - public void setSerializeStringNormally(boolean serializeStringNormally) - { - this.serializeStringNormally = serializeStringNormally; - } - - /** - * @param obj | Object to stringify directly (without formating it as string). - * - * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString}, it will be returned without ${ and }! - * - * @since 1.3.5 - */ - public static String DirectCode(Object obj) - { - return "${" + obj + "}"; - } +package org.ugp.serialx.converters; + +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +/** + * This converter is capable of converting {@link String}. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + +
StringObject
"Hello world!"new String("Hello world!")
+ * If you enter string in ${yourString}, "yourString" will be returned by {@link StringConverter#toString} according to {@link StringConverter#DirectCode}! + * + * @author PETO + * + * @since 1.3.0 + */ +public class StringConverter implements DataConverter +{ + /** + * Set this on true and {@link String} will be serialized normally, for instance "Hello world!" and not using protocols or java Base64!
+ * Setting this on false will also make Strings unreadable for normal people! + * + * @since 1.2.0 (moved to {@link StringConverter} since 1.3.0) + */ + protected boolean serializeStringNormally = true; + + protected Map parsingCache; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + String result; + int len; + if ((len = str.length()) > 1 && str.charAt(0) == '\"' && str.charAt(--len) == '\"' && indexOfNotInObj(str, ' ') == -1) + { + if (parsingCache != null) + { + if ((result = parsingCache.get(str)) != null) + return result; + parsingCache.put(str, result = str.substring(1, len)); + return result; + } + return str.substring(1, len); + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof String) + { + String str = (String) obj; + if (str.startsWith("${") && str.endsWith("}")) + { + str = str.substring(2, str.length()-1); + if (str.contains("::") && indexOfNotInObj(str, ' ') > -1) + return source.append('{').append(str).append('}'); + + if (indexOfNotInObj(str, "//") != -1) + { + source.append(str); + return null; // No append ; when ends with // + } + return source.append(str); + } + + if (serializeStringNormally) + { + if (contains(str, '\"', '\n', '\r')) + return CONTINUE; + return source.append('"').append(str).append('"'); + } + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + String str = obj.toString(); + boolean hasComment = false; + if (str.startsWith("${") && str.endsWith("}") && !(hasComment = str.substring(2).contains("//"))) + return "Manually inserted code!"; + if (!hasComment) + return new StringBuilder().append("Object of ").append(obj.getClass().getName()).append(": \"").append(obj.toString()).append("\"!"); + return ""; + } + + /** + * @param cache | Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool. Doing this can save you some memory with minimal performance overhead!
+ * Setting this to null will disable the parsing result caching by this {@link StringConverter} as it is by default.
+ * Recommended: Enable this when parsing a lot of strings that are the same, otherwise this will not have a big impact.
+ * Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! + * + * @since 1.3.8 + */ + public void setParsingCache(Map cache) + { + parsingCache = cache; + } + + /** + * @return Instance of {@link Map}, preferably {@link HashMap}, that will be used as cache for parsed strings where keys will be strings with " and values will be string without them. This cache will then be prioritized over creating a new instance of string during parsing, similarly to Java's string pool.
+ * Null will be returned if caching is disabled, which is by default...
+ * Note: Rule of thumb, is that this cache should be modified only by this converter however adding some pre-cached entries is possible but should be performed with caution! + * + * @since 1.3.8 + */ + public Map getParsingCache() + { + return parsingCache; + } + + /** + * @return Will return value of {@link StringConverter#serializeStringNormally}! + * + * @since 1.3.8 (it was static before = not good) + */ + public boolean isSerializeStringNormally() + { + return serializeStringNormally; + } + + /** + * @param serializeStringNormally | Set value of {@link StringConverter#serializeStringNormally}! + * + * @since 1.3.8 (it was static before = not good) + */ + public void setSerializeStringNormally(boolean serializeStringNormally) + { + this.serializeStringNormally = serializeStringNormally; + } + + /** + * @param obj | Object to stringify directly (without formating it as string). + * + * @return "${" + obj + "}" - if this is be inserted into {@link StringConverter#toString}, it will be returned without ${ and }! + * + * @since 1.3.5 + */ + public static String DirectCode(Object obj) + { + return "${" + obj + "}"; + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 71bf137..86f4866 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -1,114 +1,114 @@ -package org.ugp.serialx.converters; - -import static org.ugp.serialx.utils.Utils.Clone; -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.splitValues; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; - -/** - * This parser is capable of reading variables from {@link GenericScope} by using $!
- * {@link VariableParser#parse} requires one additional Scope argument in args... at index 0!
- * It also manages access member operator also known as separator ".".
- * Its case sensitive!
- * Exact outputs of this converter are based on inserted scope! - * - * @author PETO - * - * @since 1.3.8 - */ -public class VariableParser implements DataParser -{ - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (args.length > 0 && str.length() > 0 && args[0] instanceof GenericScope) - { - return parse(myHomeRegistry, str, (GenericScope) args[0], args); - } - return CONTINUE; - } - - /** - * @param source | Source object to get value of the member from (may or may not be null). Source should not be modified! - * @param member | Name/key of the member to get. - * - * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link #VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
- * Note: This method is meant to be overridden in order to add support for accessing multiple sources because by default it supports only {@link GenericScope} - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public Object getMemberOperator(Object source, Object member) - { - if (source instanceof GenericScope) - return ((GenericScope) source).variables().getOrDefault(member, VOID); - return null; - } - - /** - * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! - * @param str | Source string, should not be null or empty (preferably with some variables to read)! - * @param scope | Source scope to read from, can't be null! - * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. - * - * @return Value of variable read from scope is str was suitable. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. - * - * @since 1.3.8 - */ - protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) - { - if (str.charAt(0) == '$' && !contains(str = str.substring(1), ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) - { - boolean clsModif = str.endsWith("::class"), newModif = false; // Handle modifiers... - if (clsModif) - str = str.substring(0, str.length()-7); - else if (newModif = str.endsWith("::new")) - str = str.substring(0, str.length()-5); - - Object obj = null; - int op0Index; - if ((op0Index = str.indexOf('.')) > -1) - { - String[] path = splitValues(str, op0Index, 0, 0, new char[0], '.'); - int iLast = path.length-1; - - backlook: do - { - Object sc; - if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... - { - for (int i = 1; i < iLast; i++) // Subscope/forward lookup (inner path only)... - if ((sc = getMemberOperator(sc, path[i])) == null || sc == VOID) - { - // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[i] + "\" is not a scope but " + sc + "!", null); - break backlook; - } - - obj = getMemberOperator(sc, path[iLast]); - break; - } - } - while ((scope = scope.getParent()) != null); - } - else - { - do - { - if ((obj = scope.variables().getOrDefault(str, VOID)) != VOID) - break; - } - while ((scope = scope.getParent()) != null); - } - - if (obj == null || obj == VOID) // When was not found... - return null; - return clsModif ? obj.getClass() : newModif ? Clone(obj, scope instanceof Serializer ? ((Serializer) scope).getParsers() : DataParser.REGISTRY, new Object[0], new Scope()) : obj; - } - - return CONTINUE; - } +package org.ugp.serialx.converters; + +import static org.ugp.serialx.utils.Utils.Clone; +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.splitValues; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; + +/** + * This parser is capable of reading variables from {@link GenericScope} by using $!
+ * {@link VariableParser#parse} requires one additional Scope argument in args... at index 0!
+ * It also manages access member operator also known as separator ".".
+ * Its case sensitive!
+ * Exact outputs of this converter are based on inserted scope! + * + * @author PETO + * + * @since 1.3.8 + */ +public class VariableParser implements DataParser +{ + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (args.length > 0 && str.length() > 0 && args[0] instanceof GenericScope) + { + return parse(myHomeRegistry, str, (GenericScope) args[0], args); + } + return CONTINUE; + } + + /** + * @param source | Source object to get value of the member from (may or may not be null). Source should not be modified! + * @param member | Name/key of the member to get. + * + * @return The value of member from given source. You can think about this as ekvivalent to source.member in Java. If member with provided name/key is not present in the source or its value is not possible to get, {@link #VOID} has to be returned! If source can't be accessed/dereferenced, null has to be returned!
+ * Note: This method is meant to be overridden in order to add support for accessing multiple sources because by default it supports only {@link GenericScope} + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public Object getMemberOperator(Object source, Object member) + { + if (source instanceof GenericScope) + return ((GenericScope) source).variables().getOrDefault(member, VOID); + return null; + } + + /** + * @param myHomeRegistry | Registry where this parser is registered provided by {@link ParserRegistry#parse(String, boolean, Class, Object...)} otherwise it demands on implementation (it should not be null)! + * @param str | Source string, should not be null or empty (preferably with some variables to read)! + * @param scope | Source scope to read from, can't be null! + * @param args | Some additional args. This can be anything and it demands on implementation of DataParser. + * + * @return Value of variable read from scope is str was suitable. Special return types are {@link DataParser#VOID} and {@link DataParser#CONTINUE}. Continue will ignore this parser and jump to another one in registry. + * + * @since 1.3.8 + */ + protected Object parse(ParserRegistry myHomeRegistry, String str, GenericScope scope, Object... args) + { + if (str.charAt(0) == '$' && !contains(str = str.substring(1), ' ', '+', '-', '*', '/', '%', '>', '<', '=', '&', '|', '^', '?', '=')) + { + boolean clsModif = str.endsWith("::class"), newModif = false; // Handle modifiers... + if (clsModif) + str = str.substring(0, str.length()-7); + else if (newModif = str.endsWith("::new")) + str = str.substring(0, str.length()-5); + + Object obj = null; + int op0Index; + if ((op0Index = str.indexOf('.')) > -1) + { + String[] path = splitValues(str, op0Index, 0, 0, new char[0], '.'); + int iLast = path.length-1; + + backlook: do + { + Object sc; + if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... + { + for (int i = 1; i < iLast; i++) // Subscope/forward lookup (inner path only)... + if ((sc = getMemberOperator(sc, path[i])) == null || sc == VOID) + { + // LogProvider.instance.logErr("Value of path \"" + arg + "\" cannot be dereferenced because \"" + path[i] + "\" is not a scope but " + sc + "!", null); + break backlook; + } + + obj = getMemberOperator(sc, path[iLast]); + break; + } + } + while ((scope = scope.getParent()) != null); + } + else + { + do + { + if ((obj = scope.variables().getOrDefault(str, VOID)) != VOID) + break; + } + while ((scope = scope.getParent()) != null); + } + + if (obj == null || obj == VOID) // When was not found... + return null; + return clsModif ? obj.getClass() : newModif ? Clone(obj, scope instanceof Serializer ? ((Serializer) scope).getParsers() : DataParser.REGISTRY, new Object[0], new Scope()) : obj; + } + + return CONTINUE; + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java index b3a3e97..dca251a 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -1,148 +1,148 @@ -package org.ugp.serialx.converters.imports; - -import java.lang.reflect.Type; - -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.imports.ImportsProvider.Imports; - -/** - * This class is represents single import. It stores target class of import and its alias!
- * This imports are stored and managed in {@link Imports} and are used by many parsers and {@link Serializer}! - * - * @author PETO - * - * @since 1.3.0 - * - * @see Import - */ -public class Import implements Cloneable, Type -{ - protected final Class cls; - protected final String alias; - protected final ImportsProvider owner; - - /** - * @param cls | Class to create import for! Alias of this class will be its simple name! - * - * @since 1.3.0 - */ - public Import(Class cls) - { - this(cls, cls.getSimpleName()); - } - - /** - * @param cls | Class to create import for! Alias of this class will be its simple name! - * @param owner | Owner/provider of this Import! - * - * @since 1.3.5 - */ - public Import(Class cls, ImportsProvider owner) - { - this(cls, cls.getSimpleName(), owner); - } - - /** - * @param cls | Class to create import for! - * @param alias | Alias of class! - * - * @since 1.3.5 - */ - public Import(Class cls, String alias) - { - this(cls, alias, null); - } - - - /** - * @param cls | Class to create import for! - * @param alias | Alias of class! - * @param owner | Owner/provider of this Import! - * - * @throws IllegalArgumentException | When alias is invalid! Alias should follow java class naming conventions without necessity of package specification! - * - * @since 1.3.5 - */ - public Import(Class cls, String alias, ImportsProvider owner) throws IllegalArgumentException - { - this.cls = cls; - - if (alias.isEmpty()) - throw new IllegalArgumentException("Import alias cant be empty! Try \"" + cls.getSimpleName() + "\" instead!"); - int ch0 = alias.charAt(0); - if (ch0 == '_' || (ch0 = ch0 | ' ') >= 'a' && ch0 <= 'z') - { - this.alias = alias; - this.owner = owner; - } - else - throw new IllegalArgumentException("Import alias \"" + alias + "\" is illegal! Alias cant begin with special char or number! Try \"_" + alias + "\" instead!"); - } - - @Override - public String toString() - { - if (getCls().getSimpleName().equals(getClsAlias())) - return "import " + getCls().getName(); - return getCls().getName() + " => " + getClsAlias(); - } - - @Override - public boolean equals(Object obj) - { - if (obj instanceof String) - return getClsAlias().equals(obj); - if (obj instanceof Class) - return getCls().equals(obj); - if (obj instanceof Import) - return getClsAlias().equals(((Import) obj).getClsAlias()) && getCls().equals(((Import) obj).getCls()); - return super.equals(obj); - } - - @Override - public Import clone() - { - return new Import(getCls(), getClsAlias(), getOwner()); - } - - @Override - public String getTypeName() - { - return getClsAlias(); - } - - public Import clone(ImportsProvider newOwner) - { - return new Import(getCls(), getClsAlias(), newOwner); - } - - /** - * @return Class of this import! - * - * @since 1.3.0 - */ - public Class getCls() - { - return cls; - } - - /** - * @return Alias for class! - * - * @since 1.3.0 - */ - public String getClsAlias() - { - return alias; - } - - /** - * @return Owner/provider of this import! - * - * @since 1.3.5 - */ - public ImportsProvider getOwner() - { - return owner; - } +package org.ugp.serialx.converters.imports; + +import java.lang.reflect.Type; + +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.imports.ImportsProvider.Imports; + +/** + * This class is represents single import. It stores target class of import and its alias!
+ * This imports are stored and managed in {@link Imports} and are used by many parsers and {@link Serializer}! + * + * @author PETO + * + * @since 1.3.0 + * + * @see Import + */ +public class Import implements Cloneable, Type +{ + protected final Class cls; + protected final String alias; + protected final ImportsProvider owner; + + /** + * @param cls | Class to create import for! Alias of this class will be its simple name! + * + * @since 1.3.0 + */ + public Import(Class cls) + { + this(cls, cls.getSimpleName()); + } + + /** + * @param cls | Class to create import for! Alias of this class will be its simple name! + * @param owner | Owner/provider of this Import! + * + * @since 1.3.5 + */ + public Import(Class cls, ImportsProvider owner) + { + this(cls, cls.getSimpleName(), owner); + } + + /** + * @param cls | Class to create import for! + * @param alias | Alias of class! + * + * @since 1.3.5 + */ + public Import(Class cls, String alias) + { + this(cls, alias, null); + } + + + /** + * @param cls | Class to create import for! + * @param alias | Alias of class! + * @param owner | Owner/provider of this Import! + * + * @throws IllegalArgumentException | When alias is invalid! Alias should follow java class naming conventions without necessity of package specification! + * + * @since 1.3.5 + */ + public Import(Class cls, String alias, ImportsProvider owner) throws IllegalArgumentException + { + this.cls = cls; + + if (alias.isEmpty()) + throw new IllegalArgumentException("Import alias cant be empty! Try \"" + cls.getSimpleName() + "\" instead!"); + int ch0 = alias.charAt(0); + if (ch0 == '_' || (ch0 = ch0 | ' ') >= 'a' && ch0 <= 'z') + { + this.alias = alias; + this.owner = owner; + } + else + throw new IllegalArgumentException("Import alias \"" + alias + "\" is illegal! Alias cant begin with special char or number! Try \"_" + alias + "\" instead!"); + } + + @Override + public String toString() + { + if (getCls().getSimpleName().equals(getClsAlias())) + return "import " + getCls().getName(); + return getCls().getName() + " => " + getClsAlias(); + } + + @Override + public boolean equals(Object obj) + { + if (obj instanceof String) + return getClsAlias().equals(obj); + if (obj instanceof Class) + return getCls().equals(obj); + if (obj instanceof Import) + return getClsAlias().equals(((Import) obj).getClsAlias()) && getCls().equals(((Import) obj).getCls()); + return super.equals(obj); + } + + @Override + public Import clone() + { + return new Import(getCls(), getClsAlias(), getOwner()); + } + + @Override + public String getTypeName() + { + return getClsAlias(); + } + + public Import clone(ImportsProvider newOwner) + { + return new Import(getCls(), getClsAlias(), newOwner); + } + + /** + * @return Class of this import! + * + * @since 1.3.0 + */ + public Class getCls() + { + return cls; + } + + /** + * @return Alias for class! + * + * @since 1.3.0 + */ + public String getClsAlias() + { + return alias; + } + + /** + * @return Owner/provider of this import! + * + * @since 1.3.5 + */ + public ImportsProvider getOwner() + { + return owner; + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java index 7ab9fdb..3cfea3b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/ImportsProvider.java @@ -1,347 +1,347 @@ -package org.ugp.serialx.converters.imports; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; - -/** - * This interface is supposed to be implemented by class that can provide array of imports! - * - * @author PETO - * - * @since 1.3.5 - */ -public interface ImportsProvider -{ - /** - * Cache of Classes to their respective names/aliases.
- * Note: Treat as read only if possible! - * - * @since 1.3.8 - */ - public static final Map> CLASS_CACHE = new HashMap>(); - - /** - * List of global shared common registered imports! - * - * @since 1.3.0 - */ - public static final Imports IMPORTS = new Imports(new Import(Serializer.class), new Import(Scope.class), new Import(ArrayList.class), new Import(Math.class), new Import(Double.class), new Import(Integer.class), new Import(Double.class, "double"), new Import(Integer.class, "int"), new Import(String.class), new Import(System.class)); - - /** - * @return Array of provided imports! - * - * @since 1.3.5 - */ - Imports getImports(); - - /** - * @param obj | Object to get imports from (its supposed to be instance of {@link ImportsProvider} or collection of {@link Import})! - * - * @return Imports of object or null if object can't provide any! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public static Imports importsOf(Object obj) - { - if (obj == null) - return null; - - if (obj instanceof ImportsProvider) - return ((ImportsProvider) obj).getImports(); - - try - { - return new Imports((Collection) obj); - } - catch (Exception e) - { - return null; - } - } - - /** - * @param importProvider | Object to get imports from! - * @param aliasOrName | Alias of class or its full name! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - * - * @see ImportsProvider#importsOf(Object) - */ - public static Class forName(Object importProvider, String aliasOrName) throws ClassNotFoundException - { - return forName(importProvider, aliasOrName, true, Imports.class.getClassLoader()); - } - - /** - * @param importProvider | Object to get imports from! - * @param aliasOrName | Alias of class or its full name! - * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. - * @param loader | Class loader from which the class must be loaded. - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * If there are no dots in required alias and alias is not imported then null will be returned! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - * - * @see ImportsProvider#importsOf(Object) - */ - public static Class forName(Object importProvider, String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException - { - Class cls = getClassFor(importProvider, aliasOrName); - if (cls != null) - return cls; - - if ((cls = CLASS_CACHE.get(aliasOrName)) != null) - return cls; - if (aliasOrName.indexOf('.') > 0) - { - cls = Class.forName(aliasOrName, initialize, loader); - CLASS_CACHE.put(aliasOrName, cls); - return cls; - } - - /*try - { - return Class.forName("java.lang."+aliasOrName, initialize, loader); - } - catch (Exception e) - { - return null; - }*/ - return null; - } - - /** - * @param importProvider | Object to get imports from! - * @param cls | Class to get alias for! - * - * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! - * - * @since 1.3.5 - * - * @see ImportsProvider#importsOf(Object) - */ - public static String getAliasFor(Object importProvider, Class cls) - { - Imports imports = importsOf(importProvider); - return imports != null ? imports.getAliasFor(cls) : cls.getName(); - } - - /** - * @param importProvider | Object to get imports from! - * @param alias | Alias of class to obtain! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! - * - * @since 1.3.5 - * - * @see ImportsProvider#importsOf(Object) - */ - public static Class getClassFor(Object importProvider, String alias) - { - Imports imports = importsOf(importProvider); - return imports != null ? imports.getClassFor(alias) : null; - } - - /** - * Collection used to store and operate with {@link Import}! - * - * @author PETO - * - * @since 1.3.5 - * - * @see ImportsProvider - */ - public static class Imports extends ArrayList implements Cloneable, ImportsProvider - { - private static final long serialVersionUID = 8487976264622823940L; - - /** - * Constructs an {@link Imports} with the specified initial capacity. - * - * @param initialSize | Initial capacity. - * - * @since 1.3.5 - */ - public Imports(int initialSize) - { - super(initialSize); - } - - /** - * Constructs an {@link Imports} with inserted imports c. - * - * @param c | Initial content of registry. - * - * @since 1.3.5 - */ - public Imports(Collection c) - { - super(c); - } - - /** - * Constructs an {@link Imports} with inserted imports. - * - * @param imports | Initial content of registry. - * - * @since 1.3.5 - */ - public Imports(Import... imports) - { - addAll(imports); - } - - @Override - public Imports clone() - { - return new Imports(this); - } - - @Override - public Imports getImports() - { - return this; - } - - /** - * @param imports | Imports to add. - * - * @return {@link ArrayList#addAll(Collection)}; - * - * @since 1.3.5 - */ - public boolean addAll(Import... imports) - { - return super.addAll(Arrays.asList(imports)); - } - - /** - * @param aliasOrName | Alias of class or its full name! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - */ - public Class forName(String aliasOrName) throws ClassNotFoundException - { - return forName(aliasOrName, true, Imports.class.getClassLoader()); - } - - /** - * @param aliasOrName | Alias of class or its full name! - * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. - * @param loader | Class loader from which the class must be loaded. - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! - * If there are no dots in required alias and alias is not imported then null will be returned! - * - * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! - * - * @since 1.3.5 - */ - public Class forName(String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException - { - Class cls = getClassFor(aliasOrName); - if (cls != null) - return cls; - - if ((cls = CLASS_CACHE.get(aliasOrName)) != null) - return cls; - if (aliasOrName.indexOf('.') > 0) - { - cls = Class.forName(aliasOrName, initialize, loader); - CLASS_CACHE.put(aliasOrName, cls); - return cls; - } - /*try - { - return Class.forName("java.lang."+aliasOrName, initialize, loader); - } - catch (Exception e) - { - return null; - }*/ - return null; - } - - /** - * @param cls | Class to get alias for! - * - * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! - * - * @since 1.3.5 - */ - public String getAliasFor(Class cls) - { - for (int i = size() - 1; i >= 0; i--) - { - Import imp = get(i); - if (imp.equals(cls)) - return imp.getClsAlias(); - } - return cls.getName(); - } - - /** - * @param alias | Alias of class to obtain! - * - * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! - * - * @since 1.3.5 - */ - public Class getClassFor(String alias) - { - for (int i = size() - 1; i >= 0; i--) - { - Import imp = get(i); - if (imp.equals(alias)) - return imp.getCls(); - } - return null; - } - - /** - * @param owner | Owner of imports to get! - * - * @return Imports of provided owner stored by this list! - * - * @since 1.3.5 - */ - public Imports importsOf(ImportsProvider owner) - { - Imports imports = new Imports(); - for (Import imp : imports) - if (imp.getOwner() == owner) - imports.add(imp); - return imports; - } - - /** - * @param owner | Owner of imports to remove from this list! - * - * @since 1.3.5 - */ - public void removeImportsOf(ImportsProvider owner) - { - for (int i = size() - 1; i >= 0; i--) - if (get(i).getOwner() == owner) - remove(i); - } - } +package org.ugp.serialx.converters.imports; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; + +/** + * This interface is supposed to be implemented by class that can provide array of imports! + * + * @author PETO + * + * @since 1.3.5 + */ +public interface ImportsProvider +{ + /** + * Cache of Classes to their respective names/aliases.
+ * Note: Treat as read only if possible! + * + * @since 1.3.8 + */ + public static final Map> CLASS_CACHE = new HashMap>(); + + /** + * List of global shared common registered imports! + * + * @since 1.3.0 + */ + public static final Imports IMPORTS = new Imports(new Import(Serializer.class), new Import(Scope.class), new Import(ArrayList.class), new Import(Math.class), new Import(Double.class), new Import(Integer.class), new Import(Double.class, "double"), new Import(Integer.class, "int"), new Import(String.class), new Import(System.class)); + + /** + * @return Array of provided imports! + * + * @since 1.3.5 + */ + Imports getImports(); + + /** + * @param obj | Object to get imports from (its supposed to be instance of {@link ImportsProvider} or collection of {@link Import})! + * + * @return Imports of object or null if object can't provide any! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public static Imports importsOf(Object obj) + { + if (obj == null) + return null; + + if (obj instanceof ImportsProvider) + return ((ImportsProvider) obj).getImports(); + + try + { + return new Imports((Collection) obj); + } + catch (Exception e) + { + return null; + } + } + + /** + * @param importProvider | Object to get imports from! + * @param aliasOrName | Alias of class or its full name! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class forName(Object importProvider, String aliasOrName) throws ClassNotFoundException + { + return forName(importProvider, aliasOrName, true, Imports.class.getClassLoader()); + } + + /** + * @param importProvider | Object to get imports from! + * @param aliasOrName | Alias of class or its full name! + * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. + * @param loader | Class loader from which the class must be loaded. + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * If there are no dots in required alias and alias is not imported then null will be returned! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class forName(Object importProvider, String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException + { + Class cls = getClassFor(importProvider, aliasOrName); + if (cls != null) + return cls; + + if ((cls = CLASS_CACHE.get(aliasOrName)) != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + { + cls = Class.forName(aliasOrName, initialize, loader); + CLASS_CACHE.put(aliasOrName, cls); + return cls; + } + + /*try + { + return Class.forName("java.lang."+aliasOrName, initialize, loader); + } + catch (Exception e) + { + return null; + }*/ + return null; + } + + /** + * @param importProvider | Object to get imports from! + * @param cls | Class to get alias for! + * + * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static String getAliasFor(Object importProvider, Class cls) + { + Imports imports = importsOf(importProvider); + return imports != null ? imports.getAliasFor(cls) : cls.getName(); + } + + /** + * @param importProvider | Object to get imports from! + * @param alias | Alias of class to obtain! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! + * + * @since 1.3.5 + * + * @see ImportsProvider#importsOf(Object) + */ + public static Class getClassFor(Object importProvider, String alias) + { + Imports imports = importsOf(importProvider); + return imports != null ? imports.getClassFor(alias) : null; + } + + /** + * Collection used to store and operate with {@link Import}! + * + * @author PETO + * + * @since 1.3.5 + * + * @see ImportsProvider + */ + public static class Imports extends ArrayList implements Cloneable, ImportsProvider + { + private static final long serialVersionUID = 8487976264622823940L; + + /** + * Constructs an {@link Imports} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public Imports(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link Imports} with inserted imports c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Collection c) + { + super(c); + } + + /** + * Constructs an {@link Imports} with inserted imports. + * + * @param imports | Initial content of registry. + * + * @since 1.3.5 + */ + public Imports(Import... imports) + { + addAll(imports); + } + + @Override + public Imports clone() + { + return new Imports(this); + } + + @Override + public Imports getImports() + { + return this; + } + + /** + * @param imports | Imports to add. + * + * @return {@link ArrayList#addAll(Collection)}; + * + * @since 1.3.5 + */ + public boolean addAll(Import... imports) + { + return super.addAll(Arrays.asList(imports)); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName) throws ClassNotFoundException + { + return forName(aliasOrName, true, Imports.class.getClassLoader()); + } + + /** + * @param aliasOrName | Alias of class or its full name! + * @param initialize | If true the class will be initialized. See Section 12.4 of The Java Language Specification. + * @param loader | Class loader from which the class must be loaded. + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} similar to {@link Imports#getClassFor(String)} but this will also search via {@link Class#forName(String, boolean, ClassLoader)} if there is no import with required alias! + * If there are no dots in required alias and alias is not imported then null will be returned! + * + * @throws ClassNotFoundException when {@link Class#forName(String, boolean, ClassLoader)} throws! + * + * @since 1.3.5 + */ + public Class forName(String aliasOrName, boolean initialize, ClassLoader loader) throws ClassNotFoundException + { + Class cls = getClassFor(aliasOrName); + if (cls != null) + return cls; + + if ((cls = CLASS_CACHE.get(aliasOrName)) != null) + return cls; + if (aliasOrName.indexOf('.') > 0) + { + cls = Class.forName(aliasOrName, initialize, loader); + CLASS_CACHE.put(aliasOrName, cls); + return cls; + } + /*try + { + return Class.forName("java.lang."+aliasOrName, initialize, loader); + } + catch (Exception e) + { + return null; + }*/ + return null; + } + + /** + * @param cls | Class to get alias for! + * + * @return Alias of class picked from {@link Imports#IMPORTS} or name of class if there is no import for this class! + * + * @since 1.3.5 + */ + public String getAliasFor(Class cls) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(cls)) + return imp.getClsAlias(); + } + return cls.getName(); + } + + /** + * @param alias | Alias of class to obtain! + * + * @return Class with inserted alias picked from {@link Imports#IMPORTS} or null if there is no import with required alias! + * + * @since 1.3.5 + */ + public Class getClassFor(String alias) + { + for (int i = size() - 1; i >= 0; i--) + { + Import imp = get(i); + if (imp.equals(alias)) + return imp.getCls(); + } + return null; + } + + /** + * @param owner | Owner of imports to get! + * + * @return Imports of provided owner stored by this list! + * + * @since 1.3.5 + */ + public Imports importsOf(ImportsProvider owner) + { + Imports imports = new Imports(); + for (Import imp : imports) + if (imp.getOwner() == owner) + imports.add(imp); + return imports; + } + + /** + * @param owner | Owner of imports to remove from this list! + * + * @since 1.3.5 + */ + public void removeImportsOf(ImportsProvider owner) + { + for (int i = size() - 1; i >= 0; i--) + if (get(i).getOwner() == owner) + remove(i); + } + } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java index 1bf6709..b27c944 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/EnumProtocol.java @@ -1,31 +1,31 @@ - package org.ugp.serialx.protocols; - -/** - * EnumProtocol is universal protocol to serialize any enumerator ({@link Enum} instance). - * - * @author PETO - * - * @since 1.2.2 - */ -public class EnumProtocol extends SerializationProtocol> -{ - @Override - public Object[] serialize(Enum object) - { - return new Object[] {object.name()}; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Enum unserialize(Class> objectClass, Object... args) - { - return Enum.valueOf((Class) objectClass, args[0].toString()); - } - - @SuppressWarnings("unchecked") - @Override - public Class> applicableFor() - { - return (Class>) Enum.class; - } -} + package org.ugp.serialx.protocols; + +/** + * EnumProtocol is universal protocol to serialize any enumerator ({@link Enum} instance). + * + * @author PETO + * + * @since 1.2.2 + */ +public class EnumProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Enum object) + { + return new Object[] {object.name()}; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Enum unserialize(Class> objectClass, Object... args) + { + return Enum.valueOf((Class) objectClass, args[0].toString()); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Enum.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java index f300466..759950b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ListProtocol.java @@ -1,44 +1,44 @@ -package org.ugp.serialx.protocols; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -/** - * ListProtocol is universal protocol to serialize any {@link Collection} instance. The condition of use is public constructor with one {@link Collection} argument. - * - * @author PETO - * - * @since 1.0.0 and applicable for {@link Collection} since 1.2.2 - */ -public class ListProtocol extends SerializationProtocol> -{ - @Override - public Object[] serialize(Collection obj) - { - return obj.toArray(); - } - - @Override - public Collection unserialize(Class> objectClass, Object... args) throws Exception - { - if (objectClass.isInterface()) - return new ArrayList<>(Arrays.asList(args)); - - try - { - return objectClass.getConstructor(Collection.class).newInstance(Arrays.asList(args)); - } - catch (Exception e) - { - return objectClass.getConstructor(Object[].class).newInstance(args); - } - } - - @SuppressWarnings("unchecked") - @Override - public Class> applicableFor() - { - return (Class>) Collection.class; - } -} +package org.ugp.serialx.protocols; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; + +/** + * ListProtocol is universal protocol to serialize any {@link Collection} instance. The condition of use is public constructor with one {@link Collection} argument. + * + * @author PETO + * + * @since 1.0.0 and applicable for {@link Collection} since 1.2.2 + */ +public class ListProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Collection obj) + { + return obj.toArray(); + } + + @Override + public Collection unserialize(Class> objectClass, Object... args) throws Exception + { + if (objectClass.isInterface()) + return new ArrayList<>(Arrays.asList(args)); + + try + { + return objectClass.getConstructor(Collection.class).newInstance(Arrays.asList(args)); + } + catch (Exception e) + { + return objectClass.getConstructor(Object[].class).newInstance(args); + } + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Collection.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java index 90b46b3..4533e14 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/MapProtocol.java @@ -1,57 +1,57 @@ -package org.ugp.serialx.protocols; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.utils.LogProvider; - -/** - * ListProtocol is universal protocol to serialize any {@link Map} instance. The condition of use is public constructor with one {@link Map} argument. - * - * @author PETO - * - * @since 1.2.2 - */ -public class MapProtocol extends SerializationProtocol> -{ - @Override - public Object[] serialize(Map object) - { - Object[] args = new Object[object.size()*2]; - int i = 0; - for (Entry entry: object.entrySet()) - { - args[i] = entry.getKey(); - args[i+1] = entry.getValue(); - i+=2; - } - return args; - } - - @SuppressWarnings("unchecked") - @Override - public Map unserialize(Class> objectClass, Object... args) throws Exception - { - boolean isFromScope = args.length == 1 && args[0] instanceof GenericScope; - if (args.length % 2 != 0 && !isFromScope) - LogProvider.instance.logErr("Some variables have no values, this is not good!", null); - - if (objectClass.isInterface()) - objectClass = (Class>) HashMap.class; - - if (isFromScope) - return objectClass.getConstructor(Map.class).newInstance(((GenericScope) args[0]).variables()); - - return objectClass.getConstructor(Map.class).newInstance(GenericScope.mapKvArray(new LinkedHashMap<>(args.length/2), args)); - } - - @SuppressWarnings("unchecked") - @Override - public Class> applicableFor() - { - return (Class>) Map.class; - } -} +package org.ugp.serialx.protocols; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.utils.LogProvider; + +/** + * ListProtocol is universal protocol to serialize any {@link Map} instance. The condition of use is public constructor with one {@link Map} argument. + * + * @author PETO + * + * @since 1.2.2 + */ +public class MapProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(Map object) + { + Object[] args = new Object[object.size()*2]; + int i = 0; + for (Entry entry: object.entrySet()) + { + args[i] = entry.getKey(); + args[i+1] = entry.getValue(); + i+=2; + } + return args; + } + + @SuppressWarnings("unchecked") + @Override + public Map unserialize(Class> objectClass, Object... args) throws Exception + { + boolean isFromScope = args.length == 1 && args[0] instanceof GenericScope; + if (args.length % 2 != 0 && !isFromScope) + LogProvider.instance.logErr("Some variables have no values, this is not good!", null); + + if (objectClass.isInterface()) + objectClass = (Class>) HashMap.class; + + if (isFromScope) + return objectClass.getConstructor(Map.class).newInstance(((GenericScope) args[0]).variables()); + + return objectClass.getConstructor(Map.class).newInstance(GenericScope.mapKvArray(new LinkedHashMap<>(args.length/2), args)); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) Map.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java index e591c13..95b47d1 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/ScopeProtocol.java @@ -1,47 +1,47 @@ -package org.ugp.serialx.protocols; - -import java.util.HashMap; -import java.util.Map; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.converters.DataConverter; - - -/** - * ScopeProtocol is universal protocol to serialize any {@link GenericScope} instance. The condition of use is public constructor with arguments {@link Map} and Object[]!
- * Note: This protocol is unique in some way because it works for read only because scopes are normally serialized via {@link DataConverter} meaning calling serialize method will throw exception right away! But under normal circumstances protocols like this should not exist! - * - * @author PETO - * - * @since 1.2.2 - */ -public class ScopeProtocol extends SerializationProtocol> -{ - @Override - public Object[] serialize(GenericScope object) throws Exception - { - if (object.getClass() != Scope.class) - return new Object[] {object.castTo(Scope.class)}; - throw new UnsupportedOperationException("You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!"); - } - - @Override - public GenericScope unserialize(Class> objectClass, Object... args) throws Exception - { - if (args.length == 1 && args[0] instanceof GenericScope) - { - if (objectClass == args[0].getClass()) - return (GenericScope) args[0]; - return objectClass.getConstructor(Map.class, Object[].class).newInstance(((GenericScope) args[0]).toVarMap(), ((GenericScope) args[0]).toArray()); - } - return objectClass.getConstructor(Map.class, Object[].class).newInstance(new HashMap<>(), args); - } - - @SuppressWarnings("unchecked") - @Override - public Class> applicableFor() - { - return (Class>) GenericScope.class; - } -} +package org.ugp.serialx.protocols; + +import java.util.HashMap; +import java.util.Map; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.converters.DataConverter; + + +/** + * ScopeProtocol is universal protocol to serialize any {@link GenericScope} instance. The condition of use is public constructor with arguments {@link Map} and Object[]!
+ * Note: This protocol is unique in some way because it works for read only because scopes are normally serialized via {@link DataConverter} meaning calling serialize method will throw exception right away! But under normal circumstances protocols like this should not exist! + * + * @author PETO + * + * @since 1.2.2 + */ +public class ScopeProtocol extends SerializationProtocol> +{ + @Override + public Object[] serialize(GenericScope object) throws Exception + { + if (object.getClass() != Scope.class) + return new Object[] {object.castTo(Scope.class)}; + throw new UnsupportedOperationException("You are trying to serialize GenericScope or Scope via protocol! This is not good and should not even be possible! Scopes are meant to be serialized via converters!"); + } + + @Override + public GenericScope unserialize(Class> objectClass, Object... args) throws Exception + { + if (args.length == 1 && args[0] instanceof GenericScope) + { + if (objectClass == args[0].getClass()) + return (GenericScope) args[0]; + return objectClass.getConstructor(Map.class, Object[].class).newInstance(((GenericScope) args[0]).toVarMap(), ((GenericScope) args[0]).toArray()); + } + return objectClass.getConstructor(Map.class, Object[].class).newInstance(new HashMap<>(), args); + } + + @SuppressWarnings("unchecked") + @Override + public Class> applicableFor() + { + return (Class>) GenericScope.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java index f6f73e6..fa88030 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/SerializationProtocol.java @@ -1,455 +1,455 @@ -package org.ugp.serialx.protocols; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import org.ugp.serialx.Serializer; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Registry; - -/** - * This class supposed to be used for serializing and unserializing objects in Java by turning them in to array of Objects that can be serialized by {@link Serializer} or used by some higher entities. Also this class is capable of turning array of these objects back in to that very same Object!
- * {@link SerializationProtocol#unserialize(Class, Object...)} and {@link SerializationProtocol#serialize(Object)} are used for this conversion. - * Instance of SerializationProtocol should be registered into {@link SerializationProtocol#REGISTRY} in order to work, also only one instance of each SerializationProtocol should be used and accessed via this registry!
- * Note: Protocols should not be serializable in any way!
- * - * @author PETO - * - * @param | Generic type of object to use protocol for. - * - * @since 1.0.0 - */ -public abstract class SerializationProtocol -{ - /** - * This is serialization protocol registry. This is place where your {@link SerializationProtocol} implementations should be registered in order to work properly! Do not add there two protocols applicable for exactly same classes! - * Also I recommend to register protocols in generic order of object that are they applicable for! In other words If some object Foo has child classes, protocol of these classes should be registered after each other. - * Defaultly there are registered protocols from org.ugp.serialx.protocols. - * - * @since 1.3.0 - */ - public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class), new SelfSerializableProtocol(SelfSerializable.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new EnumProtocol()); - - /** - * This mode is for protocols that are used for serialization only! - * - * @since 1.3.5 - */ - public static final long MODE_SERIALIZE = 0b01; - - /** - * This mode is for protocols that are used for deserialization only! - * - * @since 1.3.5 - */ - public static final long MODE_DESERIALIZE = 0b10; - - /** - * This mode is for protocols that chat can both serialize and deserialize (MODE_SERIALIZE | MODE_DESERIALIZE)! - * - * @since 1.3.8 (originally known as MODE_ALL) - */ - public static final long MODE_SERIALIZE_DESERIALIZE = MODE_SERIALIZE | MODE_DESERIALIZE; - - protected boolean isActive = true; - - @Override - public boolean equals(Object obj) - { - if (obj instanceof Class) - return applicableFor().equals(obj); - if (obj instanceof SerializationProtocol) - return applicableFor().equals(((SerializationProtocol) obj).applicableFor()); - return super.equals(obj); - } - - @Override - public String toString() - { - return getClass().getName() + "[" + applicableFor().getName() + "]"; - } - - /** - * @param object | The object. - * - * @return Array of objects to serialize created from given object. - * - * @throws Exception depends on the implementation (most likely reflection related exceptions). - * - * @since 1.0.0 - */ - public abstract Object[] serialize(T object) throws Exception; - - /*/** - * @param object | The object. - * @param scope | Scope to use! - * - * @return Scope of object to serialize created from given object. - * Note: Do not use WORK IN PROGRESS! - * - * @since 1.2.2 - * - public Scope serializeAsScope(T object) - { - return null; - }*/ - - /** - * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! - * @param args | Args to create obj {@link T} from. - * - * @return New instance of object {@link T} created from args. This supposed to be an instance of object, not null! - * - * @throws Exception you can just pass exception to Serializer if you are not interested in handling it on your own. - * - * @since 1.0.0 - */ - public abstract T unserialize(Class objectClass, Object... args) throws Exception; - - /*/** - * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! - * @param scope | Scope with data to create {@link T} from. - * - * @return New instance of object {@link T} created from scopeOfArgs. - * - * @since 1.2.0 - * - public T unserialize(Class objectClass, Scope scope) throws Exception - { - return null; - }*/ - - /** - * @return Class that can be serialized using this protocol. - * In other words it should return class of object {@link T} - * - * @since 1.0.0 - */ - public abstract Class applicableFor(); - - /** - * @return Mode of this protocol, describing its type or operation mode. Can be one or more chained with binary or. Default is {@link SerializationProtocol#MODE_SERIALIZE_DESERIALIZE}! - * - * @see SerializationProtocol#MODE_DESERIALIZE - * @see SerializationProtocol#MODE_SERIALIZE - * - * @since 1.3.5 - */ - public long getMode() - { - return MODE_SERIALIZE_DESERIALIZE; - } - - /** - * @return True if this protocol is active. - * Only active protocols can be used! - * - * @since 1.0.0 - */ - public boolean isActive() - { - return isActive; - } - - /** - * @param isActive | Set this on true to activate this protocol or set this on false to deactivate it so it will not be used. - * This can be useful for example when you want to force program to serialize java.io.Serializable object using classic java.io.Serializable. - * For example when you deactivate {@link StringProtocol} program will be forced to serialize all Strings via java.io.Serializable. - * - * @since 1.0.0 - */ - public void setActive(boolean isActive) - { - this.isActive = isActive; - } - - /** - * @param object | The object. - * - * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from {@link SerializationProtocol#REGISTRY}. - * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! - * - * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. - * - * @since 1.3.0 - */ - public static Object[] serializeObj(O object) throws Exception - { - return serializeObj(REGISTRY, 0, object); - } - - /** - * @param registry | Registry to use! - * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. - * @param object | The object. - * - * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from registry. - * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! - * - * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. - * - * @since 1.3.0 - */ - public static Object[] serializeObj(ProtocolRegistry registry, long aditionalType, O object) throws Exception - { - SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE | aditionalType); - if (prot == null) - { - LogProvider.instance.logErr("Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); - return null; - } - return prot.serialize(object); - } - - /** - * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! - * @param args | Args to create obj {@link T} from. - * - * @return New instance of object {@link T} created from args. Object will be created via protocol picked from {@link SerializationProtocol#REGISTRY}. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! - * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! - * - * @throws Exception when exception occurs while unserializing object using protocol! - * - * @since 1.3.0 - */ - public static O unserializeObj(Class objectClass, Object... args) throws Exception - { - return unserializeObj(REGISTRY, 0, objectClass, args); - } - - /** - * @param registry | Registry to use! - * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. - * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! - * @param args | Args to create obj {@link T} from. - * - * @return New instance of object {@link T} created from args. Object will be created via protocol picked from registry. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! - * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! - * - * @throws Exception when exception occurs while unserializing object using protocol! - * - * @since 1.3.0 - */ - @SuppressWarnings("unchecked") - public static O unserializeObj(ProtocolRegistry registry, long aditionalType, Class objectClass, Object... args) throws Exception - { - SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE | aditionalType); - if (prot == null) - { - LogProvider.instance.logErr("Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); - return null; - } - return (O) prot.unserialize(objectClass, args); - } - - /** - * ProtocolRegistry, place to register protocols! - * - * @author PETO - * - * @since 1.0.0 (moved to SerializationProtocol since 1.3.0) - */ - public static class ProtocolRegistry extends Registry> - { - private static final long serialVersionUID = 1L; - - /** - * Constructs an {@link ProtocolRegistry} with the specified initial capacity. - * - * @param initialSize | Initial capacity. - * - * @since 1.3.5 - */ - public ProtocolRegistry(int initialSize) - { - super(initialSize); - } - - /** - * Constructs an {@link ProtocolRegistry} with content of c. - * - * @param c | Initial content of registry. - * - * @since 1.3.5 - */ - public ProtocolRegistry(Collection> c) - { - super(c); - } - - /** - * Constructs an {@link ProtocolRegistry} with protocols. - * - * @param protocols | Initial content of registry. - * - * @since 1.3.0 - */ - public ProtocolRegistry(SerializationProtocol... protocols) - { - super(protocols); - } - - @Override - public ProtocolRegistry clone() - { - return new ProtocolRegistry(this); - } - - @Override - public void add(int index, SerializationProtocol element) - { - SerializationProtocol existing; - if ((existing = GetProtocolFor(element.applicableFor(), element.getMode())) != null && element.applicableFor() == existing.applicableFor()) - LogProvider.instance.logErr("Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null); - addDuplicatively(index, element); - } - - /** - * @param protocolsClass | Protocols class. - * - * @return Protocol by its class. Pretty much equivalent with {@link Registry#get(Class)}. - * - * @since 1.0.0 - */ - public SerializationProtocol getProtocolByClass(Class> protocolsClass) - { - return get(protocolsClass); - } - - /** - * @return Sublist of any protocols that are active and can be used. - * - * @since 1.0.0 - */ - public List> GetActiveProtocols() - { - return GetActiveProtocols(-1); - } - - /** - * @return Sublist of any protocols that are not active and can't be used. - * - * @since 1.0.0 - */ - public List> GetDeactivatedProtocols() - { - return GetDeactivatedProtocols(-1); - } - - /** - * @param mode | Mode of protocols to find, or -1 if mode does not matter. - * - * @return Sublist of protocols that are active and can be used according to mode. - * - * @since 1.3.5 - */ - public List> GetActiveProtocols(long mode) - { - List> resault = new ArrayList<>(); - - for (SerializationProtocol p : this) - if (p.isActive() && (p.getMode() & mode) != 0) - resault.add(p); - return resault; - } - - /** - * @param mode | Mode of protocols to find, or -1 if mode does not matter. - * - * @return Sublist of protocols that are not active and can't be used according to mode. - * - * @since 1.3.5 - */ - public List> GetDeactivatedProtocols(long mode) - { - List> resault = new ArrayList<>(); - - for (SerializationProtocol p : this) - if (!p.isActive() && (p.getMode() & mode) != 0) - resault.add(p); - return resault; - } - - /** - * @param - * @param obj | Object that is required protocol applicable for. - * - * @return Protocol applicable for required objects class or null if there is no such an active protocol! - * - * @since 1.0.5 - */ - public SerializationProtocol GetProtocolFor(O obj) - { - return GetProtocolFor(obj, MODE_SERIALIZE_DESERIALIZE); - } - - /** - * @param - * @param applicableFor | Class of object that is protocol applicable for. - * - * @return Protocol applicable for required class or null if there is no such an active protocol! - * - * @since 1.0.0 - */ - public SerializationProtocol GetProtocolFor(Class applicableFor) - { - return GetProtocolFor(applicableFor, MODE_SERIALIZE_DESERIALIZE); - } - - /** - * @param - * @param obj | Object that is required protocol applicable for. - * @param mode | Mode of protocols to find, or -1 if mode does not matter. - * - * @return Protocol applicable for required objects class according to mode or null if there is no such an active protocol! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public SerializationProtocol GetProtocolFor(O obj, long mode) - { - return (SerializationProtocol) GetProtocolFor(obj.getClass(), mode); - } - - /** - * @param - * @param applicableFor | Class of object that is protocol applicable for. - * @param mode | Mode of protocols to find, or -1 if mode does not matter. - * - * @return Protocol applicable for required class according to mode or null if there is no such an active protocol! - * - * @since 1.3.5 - */ - @SuppressWarnings("unchecked") - public SerializationProtocol GetProtocolFor(Class applicableFor, long mode) - { - SerializationProtocol protocol = null; - for (int i = 0, len = size(); i < len; i++) - { - SerializationProtocol p = get(i); - if (p.isActive() && (p.getMode() & mode) != 0) - { - Class applicable = p.applicableFor(); - if (applicable == applicableFor) - return (SerializationProtocol) p; - if (applicable.isAssignableFrom(applicableFor)) - protocol = (SerializationProtocol) p; - } - } - return protocol; - } - - /** - * @param isActive | Activity state for all registered protocols. - * - * @since 1.0.0 - */ - public void setActivityForAll(boolean isActive) - { - for (SerializationProtocol p : this) - p.setActive(isActive); - } - } -} +package org.ugp.serialx.protocols; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +import org.ugp.serialx.Serializer; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Registry; + +/** + * This class supposed to be used for serializing and unserializing objects in Java by turning them in to array of Objects that can be serialized by {@link Serializer} or used by some higher entities. Also this class is capable of turning array of these objects back in to that very same Object!
+ * {@link SerializationProtocol#unserialize(Class, Object...)} and {@link SerializationProtocol#serialize(Object)} are used for this conversion. + * Instance of SerializationProtocol should be registered into {@link SerializationProtocol#REGISTRY} in order to work, also only one instance of each SerializationProtocol should be used and accessed via this registry!
+ * Note: Protocols should not be serializable in any way!
+ * + * @author PETO + * + * @param | Generic type of object to use protocol for. + * + * @since 1.0.0 + */ +public abstract class SerializationProtocol +{ + /** + * This is serialization protocol registry. This is place where your {@link SerializationProtocol} implementations should be registered in order to work properly! Do not add there two protocols applicable for exactly same classes! + * Also I recommend to register protocols in generic order of object that are they applicable for! In other words If some object Foo has child classes, protocol of these classes should be registered after each other. + * Defaultly there are registered protocols from org.ugp.serialx.protocols. + * + * @since 1.3.0 + */ + public static final ProtocolRegistry REGISTRY = new ProtocolRegistry(/*This might be unsafe: new UniversalObjectInstantiationProtocol<>(Object.class), new SelfSerializableProtocol(SelfSerializable.class),*/ new ListProtocol(), new MapProtocol(), new StringProtocol(), new ScopeProtocol(), new EnumProtocol()); + + /** + * This mode is for protocols that are used for serialization only! + * + * @since 1.3.5 + */ + public static final long MODE_SERIALIZE = 0b01; + + /** + * This mode is for protocols that are used for deserialization only! + * + * @since 1.3.5 + */ + public static final long MODE_DESERIALIZE = 0b10; + + /** + * This mode is for protocols that chat can both serialize and deserialize (MODE_SERIALIZE | MODE_DESERIALIZE)! + * + * @since 1.3.8 (originally known as MODE_ALL) + */ + public static final long MODE_SERIALIZE_DESERIALIZE = MODE_SERIALIZE | MODE_DESERIALIZE; + + protected boolean isActive = true; + + @Override + public boolean equals(Object obj) + { + if (obj instanceof Class) + return applicableFor().equals(obj); + if (obj instanceof SerializationProtocol) + return applicableFor().equals(((SerializationProtocol) obj).applicableFor()); + return super.equals(obj); + } + + @Override + public String toString() + { + return getClass().getName() + "[" + applicableFor().getName() + "]"; + } + + /** + * @param object | The object. + * + * @return Array of objects to serialize created from given object. + * + * @throws Exception depends on the implementation (most likely reflection related exceptions). + * + * @since 1.0.0 + */ + public abstract Object[] serialize(T object) throws Exception; + + /*/** + * @param object | The object. + * @param scope | Scope to use! + * + * @return Scope of object to serialize created from given object. + * Note: Do not use WORK IN PROGRESS! + * + * @since 1.2.2 + * + public Scope serializeAsScope(T object) + { + return null; + }*/ + + /** + * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. This supposed to be an instance of object, not null! + * + * @throws Exception you can just pass exception to Serializer if you are not interested in handling it on your own. + * + * @since 1.0.0 + */ + public abstract T unserialize(Class objectClass, Object... args) throws Exception; + + /*/** + * @param objectClass | The class of object that should be created. This can be useful when object {@link T} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! + * @param scope | Scope with data to create {@link T} from. + * + * @return New instance of object {@link T} created from scopeOfArgs. + * + * @since 1.2.0 + * + public T unserialize(Class objectClass, Scope scope) throws Exception + { + return null; + }*/ + + /** + * @return Class that can be serialized using this protocol. + * In other words it should return class of object {@link T} + * + * @since 1.0.0 + */ + public abstract Class applicableFor(); + + /** + * @return Mode of this protocol, describing its type or operation mode. Can be one or more chained with binary or. Default is {@link SerializationProtocol#MODE_SERIALIZE_DESERIALIZE}! + * + * @see SerializationProtocol#MODE_DESERIALIZE + * @see SerializationProtocol#MODE_SERIALIZE + * + * @since 1.3.5 + */ + public long getMode() + { + return MODE_SERIALIZE_DESERIALIZE; + } + + /** + * @return True if this protocol is active. + * Only active protocols can be used! + * + * @since 1.0.0 + */ + public boolean isActive() + { + return isActive; + } + + /** + * @param isActive | Set this on true to activate this protocol or set this on false to deactivate it so it will not be used. + * This can be useful for example when you want to force program to serialize java.io.Serializable object using classic java.io.Serializable. + * For example when you deactivate {@link StringProtocol} program will be forced to serialize all Strings via java.io.Serializable. + * + * @since 1.0.0 + */ + public void setActive(boolean isActive) + { + this.isActive = isActive; + } + + /** + * @param object | The object. + * + * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from {@link SerializationProtocol#REGISTRY}. + * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! + * + * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. + * + * @since 1.3.0 + */ + public static Object[] serializeObj(O object) throws Exception + { + return serializeObj(REGISTRY, 0, object); + } + + /** + * @param registry | Registry to use! + * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. + * @param object | The object. + * + * @return Array of objects to serialize created from given object. Object will be serialized via protocol picked from registry. + * {@link SerializationProtocol#serialize(Class, Object...)} method of picked protocol will be called! Null will be returned if no protocol was found and you will be prompted with error message! + * + * @throws Exception Depends on the implementation of {@link SerializationProtocol#serialize(Object)}. + * + * @since 1.3.0 + */ + public static Object[] serializeObj(ProtocolRegistry registry, long aditionalType, O object) throws Exception + { + SerializationProtocol prot = registry.GetProtocolFor(object, MODE_SERIALIZE | aditionalType); + if (prot == null) + { + LogProvider.instance.logErr("Unable to serialize \"" + object + "\" because there is no registered and active protocol for serializing " + object.getClass() + "!", null); + return null; + } + return prot.serialize(object); + } + + /** + * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. Object will be created via protocol picked from {@link SerializationProtocol#REGISTRY}. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! + * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! + * + * @throws Exception when exception occurs while unserializing object using protocol! + * + * @since 1.3.0 + */ + public static O unserializeObj(Class objectClass, Object... args) throws Exception + { + return unserializeObj(REGISTRY, 0, objectClass, args); + } + + /** + * @param registry | Registry to use! + * @param aditionalType | Additional protocol mode that will be chained together with {@link SerializationProtocol#MODE_DESERIALIZE}. + * @param objectClass | The class of object that should be created. This can be useful when object {@link O} has children classes with same constructors. You can use reflection to make protocol working also for these child classes! This class is also used to pick suitable protocol! + * @param args | Args to create obj {@link T} from. + * + * @return New instance of object {@link T} created from args. Object will be created via protocol picked from registry. If there is no protocol registered for objectClass null will be returned and you will be prompted in console! + * {@link SerializationProtocol#unserialize(Class, Object...)} method of picked protocol will be called! + * + * @throws Exception when exception occurs while unserializing object using protocol! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public static O unserializeObj(ProtocolRegistry registry, long aditionalType, Class objectClass, Object... args) throws Exception + { + SerializationProtocol prot = (SerializationProtocol) registry.GetProtocolFor(objectClass, MODE_DESERIALIZE | aditionalType); + if (prot == null) + { + LogProvider.instance.logErr("Unable to unserialize " + Arrays.toString(args) + " because there is no registered and active protocol for unserializing \"" + objectClass + "\"!", null); + return null; + } + return (O) prot.unserialize(objectClass, args); + } + + /** + * ProtocolRegistry, place to register protocols! + * + * @author PETO + * + * @since 1.0.0 (moved to SerializationProtocol since 1.3.0) + */ + public static class ProtocolRegistry extends Registry> + { + private static final long serialVersionUID = 1L; + + /** + * Constructs an {@link ProtocolRegistry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.5 + */ + public ProtocolRegistry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link ProtocolRegistry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.5 + */ + public ProtocolRegistry(Collection> c) + { + super(c); + } + + /** + * Constructs an {@link ProtocolRegistry} with protocols. + * + * @param protocols | Initial content of registry. + * + * @since 1.3.0 + */ + public ProtocolRegistry(SerializationProtocol... protocols) + { + super(protocols); + } + + @Override + public ProtocolRegistry clone() + { + return new ProtocolRegistry(this); + } + + @Override + public void add(int index, SerializationProtocol element) + { + SerializationProtocol existing; + if ((existing = GetProtocolFor(element.applicableFor(), element.getMode())) != null && element.applicableFor() == existing.applicableFor()) + LogProvider.instance.logErr("Protocol applicable for \"" + element.applicableFor().getName() + "\" is already registred!", null); + addDuplicatively(index, element); + } + + /** + * @param protocolsClass | Protocols class. + * + * @return Protocol by its class. Pretty much equivalent with {@link Registry#get(Class)}. + * + * @since 1.0.0 + */ + public SerializationProtocol getProtocolByClass(Class> protocolsClass) + { + return get(protocolsClass); + } + + /** + * @return Sublist of any protocols that are active and can be used. + * + * @since 1.0.0 + */ + public List> GetActiveProtocols() + { + return GetActiveProtocols(-1); + } + + /** + * @return Sublist of any protocols that are not active and can't be used. + * + * @since 1.0.0 + */ + public List> GetDeactivatedProtocols() + { + return GetDeactivatedProtocols(-1); + } + + /** + * @param mode | Mode of protocols to find, or -1 if mode does not matter. + * + * @return Sublist of protocols that are active and can be used according to mode. + * + * @since 1.3.5 + */ + public List> GetActiveProtocols(long mode) + { + List> resault = new ArrayList<>(); + + for (SerializationProtocol p : this) + if (p.isActive() && (p.getMode() & mode) != 0) + resault.add(p); + return resault; + } + + /** + * @param mode | Mode of protocols to find, or -1 if mode does not matter. + * + * @return Sublist of protocols that are not active and can't be used according to mode. + * + * @since 1.3.5 + */ + public List> GetDeactivatedProtocols(long mode) + { + List> resault = new ArrayList<>(); + + for (SerializationProtocol p : this) + if (!p.isActive() && (p.getMode() & mode) != 0) + resault.add(p); + return resault; + } + + /** + * @param + * @param obj | Object that is required protocol applicable for. + * + * @return Protocol applicable for required objects class or null if there is no such an active protocol! + * + * @since 1.0.5 + */ + public SerializationProtocol GetProtocolFor(O obj) + { + return GetProtocolFor(obj, MODE_SERIALIZE_DESERIALIZE); + } + + /** + * @param + * @param applicableFor | Class of object that is protocol applicable for. + * + * @return Protocol applicable for required class or null if there is no such an active protocol! + * + * @since 1.0.0 + */ + public SerializationProtocol GetProtocolFor(Class applicableFor) + { + return GetProtocolFor(applicableFor, MODE_SERIALIZE_DESERIALIZE); + } + + /** + * @param + * @param obj | Object that is required protocol applicable for. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. + * + * @return Protocol applicable for required objects class according to mode or null if there is no such an active protocol! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public SerializationProtocol GetProtocolFor(O obj, long mode) + { + return (SerializationProtocol) GetProtocolFor(obj.getClass(), mode); + } + + /** + * @param + * @param applicableFor | Class of object that is protocol applicable for. + * @param mode | Mode of protocols to find, or -1 if mode does not matter. + * + * @return Protocol applicable for required class according to mode or null if there is no such an active protocol! + * + * @since 1.3.5 + */ + @SuppressWarnings("unchecked") + public SerializationProtocol GetProtocolFor(Class applicableFor, long mode) + { + SerializationProtocol protocol = null; + for (int i = 0, len = size(); i < len; i++) + { + SerializationProtocol p = get(i); + if (p.isActive() && (p.getMode() & mode) != 0) + { + Class applicable = p.applicableFor(); + if (applicable == applicableFor) + return (SerializationProtocol) p; + if (applicable.isAssignableFrom(applicableFor)) + protocol = (SerializationProtocol) p; + } + } + return protocol; + } + + /** + * @param isActive | Activity state for all registered protocols. + * + * @since 1.0.0 + */ + public void setActivityForAll(boolean isActive) + { + for (SerializationProtocol p : this) + p.setActive(isActive); + } + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java b/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java index 68e1529..be194b1 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/protocols/StringProtocol.java @@ -1,62 +1,62 @@ -package org.ugp.serialx.protocols; - -/** - * StringProtocol is universal protocol to serialize any {@link CharSequence} instance. The condition of use is public constructor with one {@link String} or byte[] argument. - * - * @author PETO - * - * @since 1.0.0 and universal for {@link CharSequence} since 1.2.0 - */ -public class StringProtocol extends SerializationProtocol -{ - @Override - public Object[] serialize(CharSequence object) - { - int len = object.length(); - Object[] chars = new Object[len]; - - for (int i = 0; i < len; i++) - chars[i] = (int) object.charAt(i); - return chars; - } - - @Override - public CharSequence unserialize(Class objectClass, Object... args) throws Exception - { - if (args.length == 1 && args[0] instanceof CharSequence) - return (CharSequence) args[0]; - - if (objectClass.isInterface()) - objectClass = String.class; - - char[] chars = new char[args.length]; - for (int i = 0; i < args.length; i++) - if (args[i] != null) - { - if (args[i] instanceof Character) - chars[i] = (char) args[i]; - else - chars[i] = (char)((Number) args[i]).intValue(); - } - else - break; - - String str = new String(chars); - if (objectClass == String.class) - return str; - try - { - return objectClass.getConstructor(String.class).newInstance(str); - } - catch (Exception e) - { - return objectClass.getConstructor(char[].class).newInstance(chars); - } - } - - @Override - public Class applicableFor() - { - return CharSequence.class; - } -} +package org.ugp.serialx.protocols; + +/** + * StringProtocol is universal protocol to serialize any {@link CharSequence} instance. The condition of use is public constructor with one {@link String} or byte[] argument. + * + * @author PETO + * + * @since 1.0.0 and universal for {@link CharSequence} since 1.2.0 + */ +public class StringProtocol extends SerializationProtocol +{ + @Override + public Object[] serialize(CharSequence object) + { + int len = object.length(); + Object[] chars = new Object[len]; + + for (int i = 0; i < len; i++) + chars[i] = (int) object.charAt(i); + return chars; + } + + @Override + public CharSequence unserialize(Class objectClass, Object... args) throws Exception + { + if (args.length == 1 && args[0] instanceof CharSequence) + return (CharSequence) args[0]; + + if (objectClass.isInterface()) + objectClass = String.class; + + char[] chars = new char[args.length]; + for (int i = 0; i < args.length; i++) + if (args[i] != null) + { + if (args[i] instanceof Character) + chars[i] = (char) args[i]; + else + chars[i] = (char)((Number) args[i]).intValue(); + } + else + break; + + String str = new String(chars); + if (objectClass == String.class) + return str; + try + { + return objectClass.getConstructor(String.class).newInstance(str); + } + catch (Exception e) + { + return objectClass.getConstructor(char[].class).newInstance(chars); + } + } + + @Override + public Class applicableFor() + { + return CharSequence.class; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java index f4fc843..a7c24e8 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/LogProvider.java @@ -1,75 +1,75 @@ -package org.ugp.serialx.utils; - -/** - * Log provider used for logging in SerialX. - * You can use to to easily implement log4j or other logging utilities. - * - * @author PETO - * - * @since 1.3.5 - */ -public class LogProvider -{ - protected boolean reThrowException; - - public static LogProvider instance = new LogProvider(); - - /** - * @param obj | Object to log in normal mode! - * - * @since 1.3.5 - */ - public void logOut(Object obj) - { - System.out.println(obj); - } - - /** - * @param obj | Object to log in error mode! - * @param ex | Exception that cause the error! - * - * @throws RuntimeException | Of "ex" if exception re-throwing is enabled! - * - * @since 1.3.5 - */ - public void logErr(Object obj, Throwable ex) - { - if (reThrowException) - { - if (ex == null || ex.getMessage() == null || ex.getMessage().isEmpty()) - throw new RuntimeException(String.valueOf(obj)); - throw new RuntimeException(ex); - } - - try - { - StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; - String callerName = caller.getClassName(); - System.err.println(callerName.substring(callerName.lastIndexOf('.')+1) + "#" + caller.getMethodName() + ": " + obj); - } - catch (Exception e) - { - System.err.println(obj); - } - } - - /** - * @return If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! - * - * @since 1.3.5 - */ - public boolean isReThrowException() - { - return reThrowException; - } - - /** - * @param reThrowException | If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! - * - * @since 1.3.5 - */ - public void setReThrowException(boolean reThrowException) - { - this.reThrowException = reThrowException; - } -} +package org.ugp.serialx.utils; + +/** + * Log provider used for logging in SerialX. + * You can use to to easily implement log4j or other logging utilities. + * + * @author PETO + * + * @since 1.3.5 + */ +public class LogProvider +{ + protected boolean reThrowException; + + public static LogProvider instance = new LogProvider(); + + /** + * @param obj | Object to log in normal mode! + * + * @since 1.3.5 + */ + public void logOut(Object obj) + { + System.out.println(obj); + } + + /** + * @param obj | Object to log in error mode! + * @param ex | Exception that cause the error! + * + * @throws RuntimeException | Of "ex" if exception re-throwing is enabled! + * + * @since 1.3.5 + */ + public void logErr(Object obj, Throwable ex) + { + if (reThrowException) + { + if (ex == null || ex.getMessage() == null || ex.getMessage().isEmpty()) + throw new RuntimeException(String.valueOf(obj)); + throw new RuntimeException(ex); + } + + try + { + StackTraceElement caller = Thread.currentThread().getStackTrace()[2]; + String callerName = caller.getClassName(); + System.err.println(callerName.substring(callerName.lastIndexOf('.')+1) + "#" + caller.getMethodName() + ": " + obj); + } + catch (Exception e) + { + System.err.println(obj); + } + } + + /** + * @return If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! + * + * @since 1.3.5 + */ + public boolean isReThrowException() + { + return reThrowException; + } + + /** + * @param reThrowException | If true, exception or error object will be rethrown as {@link RuntimeException} by {@link LogProvider#logErr(Object, Throwable)}! + * + * @since 1.3.5 + */ + public void setReThrowException(boolean reThrowException) + { + this.reThrowException = reThrowException; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java index 8e6db5d..d47b935 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/Registry.java @@ -1,421 +1,421 @@ -package org.ugp.serialx.utils; - -import java.util.ArrayList; -import java.util.Collection; - -/** - * This is list that can contains only one element per class! Trying to add 2 elements with same class will cause old one to be removed and new one will be added! - * - * @author PETO - * - * @param | The type of elements held in this collection - * - * @since 1.3.0 - */ -public class Registry extends ArrayList -{ - private static final long serialVersionUID = 1L; - - /** - * Constructs an {@link Registry} with the specified initial capacity. - * - * @param initialSize | Initial capacity. - * - * @since 1.3.0 - */ - public Registry(int initialSize) - { - super(initialSize); - } - - /** - * Constructs an {@link Registry} with content of c. - * - * @param c | Initial content of registry. - * - * @since 1.3.0 - */ - public Registry(Collection c) - { - super(c); - } - - /** - * Constructs an {@link Registry} with objs. - * - * @param objs | Initial content of registry. - * - * @since 1.3.0 - */ - @SafeVarargs - public Registry(E... objs) - { - addAll(objs); - } - - @Override - public Registry clone() - { - return new Registry<>(this); - } - - @Override - public boolean addAll(Collection c) - { - return addAll(size(), c); - } - - @Override - public boolean addAll(int index, Collection c) - { - for (E s : c) - add(index++, s); - return true; - } - - @Override - public boolean add(E e) - { - add(size(), e); - return true; - } - - @SuppressWarnings("unchecked") - @Override - public void add(int index, E element) - { - E contained = get((Class) element.getClass()); - if (contained != null) - remove(contained); - super.add(index, element); - } - - /** - * @param exclude | Class of elements to exclude! - * - * @return Clone of this registry, excluding elements of inserted classes! - * - * @since 1.3.0 - */ - public Registry clone(Class... exclude) - { - Registry clone = clone(); - - for (int i = clone.size() - 1; i >= 0; i--) - { - E e = clone.get(i); - for (Class cls : exclude) - if (e.getClass() == cls) - clone.remove(e); - } - return clone; - } - - /** - * Similar to regular add however this one will not remove existing element if duplicate (should not be public)! - * Essentially it will simply do super.add(index, element)! - * - * @param index | Index at which the specified element is to be inserted! - * @param element | Element to add! - * - * @since 1.3.0 - */ - protected void addDuplicatively(int index, E element) - { - super.add(index, element); - } - - /** - * @param elms | Array o elements to add! - * - * @since 1.3.0 - */ - public void addAll(@SuppressWarnings("unchecked") E... elms) - { - addAll(size(), elms); - } - - /** - * @param index | Index at which the specified elements should be inserted - * @param elms | Array o elements to add! - * - * @since 1.3.0 - */ - public void addAll(int index, @SuppressWarnings("unchecked") E... elms) - { - for (E s : elms) - add(index++, s); - } - - /** - * @param elm | Class of element to add! - * - * @return Instantiated obj of inserted class that was added. Empty constructor required! - * - * @throws Exception - * - * @since 1.3.0 - */ - public E add(Class elm) throws Exception - { - E inst = elm.getConstructor().newInstance(); - add(inst); - return inst; - } - - /** - * @param elms | Array of classes to be instantiated and added! - * - * @throws Exception - * - * @since 1.3.0 - */ - public void addAll(@SuppressWarnings("unchecked") Class... elms) throws Exception - { - for (Class cls : elms) - add(cls); - } - - /** - * @param cls | Class to find! - * @param element | Element to insert before index of required class! - * - * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} - * - * @since 1.3.0 - */ - public int addBefore(Class cls, E element) - { - return addBefore(cls, false, element); - } - - /** - * @param cls | Class to find! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * @param element | Element to insert before index of required class! - * - * @return {@link Registry#indexOf(Class, boolean)} - * - * @since 1.3.0 - */ - public int addBefore(Class cls, boolean includeChildrens, E element) - { - int index = indexOf(cls, includeChildrens); - if (index <= -1) - add(element); - else - add(index, element); - return index; - } - - /** - * @param cls | Class to find! - * @param element | Element to insert after index of required class! - * - * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} - * - * @since 1.3.0 - */ - public int addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element) - { - return addAllBefore(cls, false, element); - } - - /** - * @param cls | Class to find! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * @param element | Element to insert after index of required class! - * - * @return {@link Registry#indexOf(Class, boolean)} - * - * @since 1.3.0 - */ - public int addAllBefore(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) - { - int index = indexOf(cls, includeChildrens); - if (index <= -1) - addAll(element); - else - addAll(index, element); - return index; - } - - /** - * @param cls | Class to find! - * @param element | Element to insert after index of required class! - * - * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} - * - * @since 1.3.0 - */ - public int addAfter(Class cls, E element) - { - return addAfter(cls, false, element); - } - - /** - * @param cls | Class to find! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * @param element | Element to insert after index of required class! - * - * @return {@link Registry#indexOf(Class, boolean)} - * - * @since 1.3.0 - */ - public int addAfter(Class cls, boolean includeChildrens, E element) - { - int index = indexOf(cls, includeChildrens); - if (index <= -1) - add(element); - else - add(index + 1, element); - return index; - } - - /** - * @param cls | Class to find! - * @param element | Element to insert after index of required class! - * - * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} - * - * @since 1.3.0 - */ - public int addAllAfter(Class cls, @SuppressWarnings("unchecked") E... element) - { - return addAllAfter(cls, false, element); - } - - /** - * @param cls | Class to find! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * @param element | Element to insert after index of required class! - * - * @return {@link Registry#indexOf(Class, boolean)} - * - * @since 1.3.0 - */ - public int addAllAfter(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) - { - int index = indexOf(cls, includeChildrens); - if (index <= -1) - addAll(element); - else - addAll(index + 1, element); - return index; - } - - /** - * @param cls | Class to get instance for! - * - * @return Element of class or null if there is no such a one! - * - * @since 1.3.0 - */ - public C get(Class cls) - { - return get(cls, false); - } - - /** - * @param cls | Class to get instance for! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * - * @return Element of class according to includeChildrens flag or null if there is no such a one! - * - * @since 1.3.0 - */ - @SuppressWarnings("unchecked") - public C get(Class cls, boolean includeChildrens) - { - C obj = null; - for (int i = 0, size = size(); i < size; i++) - { - C elm = (C) get(i); - Class objCls; - if ((objCls = elm.getClass()) == cls) - return elm; - if (includeChildrens && cls.isAssignableFrom(objCls)) - obj = elm; - } - return obj; - } - - /** - * @param cls | Instances class to get index of! - * - * @return Index of element with required class or -1 if there is no such a one! - * - * @since 1.3.0 - */ - public int indexOf(Class cls) - { - return indexOf(cls, false); - } - - /** - * @param cls | Instances class to get index of! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * - * @return Index of element with class according to includeChildrens flag or -1 if there is no such a one! - * - * @since 1.3.0 - */ - public int indexOf(Class cls, boolean includeChildrens) - { - int index = -1; - for (int i = 0; i < size(); i++) - { - Class objCls = get(i).getClass(); - if (objCls == cls) - return i; - if (includeChildrens && cls.isAssignableFrom(objCls)) - index = i; - } - return index; - } - - /** - * @param cls | Class of element to remove! - * - * @return Removed element itself! - * - * @since 1.3.0 - */ - public E remove(Class cls) - { - return remove(cls, false); - } - - - /** - * @param cls | Class of element to remove! - * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! - * - * @return Removed element itself or null if there is no element with cls! - * - * @since 1.3.0 - */ - public E remove(Class cls, boolean includeChildrens) - { - int i = indexOf(cls, includeChildrens); - if (i > -1) - return remove(i); - return null; - } - - - /** - * @param newContent | New content to set, old one will be deleted! - * - * @return Registry with previous content! - * - * @since 1.3.0 - */ - public Registry setTo(Registry newContent) - { - Registry old = clone(); - clear(); - addAll(newContent); - return old; - } -} +package org.ugp.serialx.utils; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * This is list that can contains only one element per class! Trying to add 2 elements with same class will cause old one to be removed and new one will be added! + * + * @author PETO + * + * @param | The type of elements held in this collection + * + * @since 1.3.0 + */ +public class Registry extends ArrayList +{ + private static final long serialVersionUID = 1L; + + /** + * Constructs an {@link Registry} with the specified initial capacity. + * + * @param initialSize | Initial capacity. + * + * @since 1.3.0 + */ + public Registry(int initialSize) + { + super(initialSize); + } + + /** + * Constructs an {@link Registry} with content of c. + * + * @param c | Initial content of registry. + * + * @since 1.3.0 + */ + public Registry(Collection c) + { + super(c); + } + + /** + * Constructs an {@link Registry} with objs. + * + * @param objs | Initial content of registry. + * + * @since 1.3.0 + */ + @SafeVarargs + public Registry(E... objs) + { + addAll(objs); + } + + @Override + public Registry clone() + { + return new Registry<>(this); + } + + @Override + public boolean addAll(Collection c) + { + return addAll(size(), c); + } + + @Override + public boolean addAll(int index, Collection c) + { + for (E s : c) + add(index++, s); + return true; + } + + @Override + public boolean add(E e) + { + add(size(), e); + return true; + } + + @SuppressWarnings("unchecked") + @Override + public void add(int index, E element) + { + E contained = get((Class) element.getClass()); + if (contained != null) + remove(contained); + super.add(index, element); + } + + /** + * @param exclude | Class of elements to exclude! + * + * @return Clone of this registry, excluding elements of inserted classes! + * + * @since 1.3.0 + */ + public Registry clone(Class... exclude) + { + Registry clone = clone(); + + for (int i = clone.size() - 1; i >= 0; i--) + { + E e = clone.get(i); + for (Class cls : exclude) + if (e.getClass() == cls) + clone.remove(e); + } + return clone; + } + + /** + * Similar to regular add however this one will not remove existing element if duplicate (should not be public)! + * Essentially it will simply do super.add(index, element)! + * + * @param index | Index at which the specified element is to be inserted! + * @param element | Element to add! + * + * @since 1.3.0 + */ + protected void addDuplicatively(int index, E element) + { + super.add(index, element); + } + + /** + * @param elms | Array o elements to add! + * + * @since 1.3.0 + */ + public void addAll(@SuppressWarnings("unchecked") E... elms) + { + addAll(size(), elms); + } + + /** + * @param index | Index at which the specified elements should be inserted + * @param elms | Array o elements to add! + * + * @since 1.3.0 + */ + public void addAll(int index, @SuppressWarnings("unchecked") E... elms) + { + for (E s : elms) + add(index++, s); + } + + /** + * @param elm | Class of element to add! + * + * @return Instantiated obj of inserted class that was added. Empty constructor required! + * + * @throws Exception + * + * @since 1.3.0 + */ + public E add(Class elm) throws Exception + { + E inst = elm.getConstructor().newInstance(); + add(inst); + return inst; + } + + /** + * @param elms | Array of classes to be instantiated and added! + * + * @throws Exception + * + * @since 1.3.0 + */ + public void addAll(@SuppressWarnings("unchecked") Class... elms) throws Exception + { + for (Class cls : elms) + add(cls); + } + + /** + * @param cls | Class to find! + * @param element | Element to insert before index of required class! + * + * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} + * + * @since 1.3.0 + */ + public int addBefore(Class cls, E element) + { + return addBefore(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert before index of required class! + * + * @return {@link Registry#indexOf(Class, boolean)} + * + * @since 1.3.0 + */ + public int addBefore(Class cls, boolean includeChildrens, E element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + add(element); + else + add(index, element); + return index; + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} + * + * @since 1.3.0 + */ + public int addAllBefore(Class cls, @SuppressWarnings("unchecked") E... element) + { + return addAllBefore(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @return {@link Registry#indexOf(Class, boolean)} + * + * @since 1.3.0 + */ + public int addAllBefore(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + addAll(element); + else + addAll(index, element); + return index; + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @return Index where the element was inserted. {@link Registry#indexOf(cls, false)} + * + * @since 1.3.0 + */ + public int addAfter(Class cls, E element) + { + return addAfter(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @return {@link Registry#indexOf(Class, boolean)} + * + * @since 1.3.0 + */ + public int addAfter(Class cls, boolean includeChildrens, E element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + add(element); + else + add(index + 1, element); + return index; + } + + /** + * @param cls | Class to find! + * @param element | Element to insert after index of required class! + * + * @return Index where the elements were inserted. {@link Registry#indexOf(cls, false)} + * + * @since 1.3.0 + */ + public int addAllAfter(Class cls, @SuppressWarnings("unchecked") E... element) + { + return addAllAfter(cls, false, element); + } + + /** + * @param cls | Class to find! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * @param element | Element to insert after index of required class! + * + * @return {@link Registry#indexOf(Class, boolean)} + * + * @since 1.3.0 + */ + public int addAllAfter(Class cls, boolean includeChildrens, @SuppressWarnings("unchecked") E... element) + { + int index = indexOf(cls, includeChildrens); + if (index <= -1) + addAll(element); + else + addAll(index + 1, element); + return index; + } + + /** + * @param cls | Class to get instance for! + * + * @return Element of class or null if there is no such a one! + * + * @since 1.3.0 + */ + public C get(Class cls) + { + return get(cls, false); + } + + /** + * @param cls | Class to get instance for! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Element of class according to includeChildrens flag or null if there is no such a one! + * + * @since 1.3.0 + */ + @SuppressWarnings("unchecked") + public C get(Class cls, boolean includeChildrens) + { + C obj = null; + for (int i = 0, size = size(); i < size; i++) + { + C elm = (C) get(i); + Class objCls; + if ((objCls = elm.getClass()) == cls) + return elm; + if (includeChildrens && cls.isAssignableFrom(objCls)) + obj = elm; + } + return obj; + } + + /** + * @param cls | Instances class to get index of! + * + * @return Index of element with required class or -1 if there is no such a one! + * + * @since 1.3.0 + */ + public int indexOf(Class cls) + { + return indexOf(cls, false); + } + + /** + * @param cls | Instances class to get index of! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Index of element with class according to includeChildrens flag or -1 if there is no such a one! + * + * @since 1.3.0 + */ + public int indexOf(Class cls, boolean includeChildrens) + { + int index = -1; + for (int i = 0; i < size(); i++) + { + Class objCls = get(i).getClass(); + if (objCls == cls) + return i; + if (includeChildrens && cls.isAssignableFrom(objCls)) + index = i; + } + return index; + } + + /** + * @param cls | Class of element to remove! + * + * @return Removed element itself! + * + * @since 1.3.0 + */ + public E remove(Class cls) + { + return remove(cls, false); + } + + + /** + * @param cls | Class of element to remove! + * @param includeChildrens | If true, index of child classes of cls will be returned when object with exactly matching class is not registered! + * + * @return Removed element itself or null if there is no element with cls! + * + * @since 1.3.0 + */ + public E remove(Class cls, boolean includeChildrens) + { + int i = indexOf(cls, includeChildrens); + if (i > -1) + return remove(i); + return null; + } + + + /** + * @param newContent | New content to set, old one will be deleted! + * + * @return Registry with previous content! + * + * @since 1.3.0 + */ + public Registry setTo(Registry newContent) + { + Registry old = clone(); + clear(); + addAll(newContent); + return old; + } +} diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java index 72ce194..4e9bd68 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java @@ -1,941 +1,941 @@ -package org.ugp.serialx.utils; - -import static org.ugp.serialx.converters.DataParser.VOID; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.HttpURLConnection; -import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.protocols.SerializationProtocol; - -/** - * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection. - * - * @author PETO - * - * @since 1.3.8 - */ -public final class Utils { - private Utils() {} - - /** - * {@link System#lineSeparator()} - * - * @since 1.3.9 - */ - public static final char[] ENDL = System.lineSeparator().toCharArray(); - - /** - * @param f | Source file. - * - * @return All lines from source file as string. - * @throws IOException - * - * @since 1.1.5 - */ - public static String LoadFileToString(File f) throws IOException - { - return LoadFileToString(f, 1); - } - - /** - * @param f | Source file. - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Content of file as string. - * @throws IOException - * - * @since 1.2.0 - */ - public static String LoadFileToString(File f, int endlMode) throws IOException - { - return StreamToString(new FileReader(f), endlMode); - } - - /** - * @param input | Input stream to read to string! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.5 - */ - public static String StreamToString(InputStream input, int endlMode) throws IOException - { - return StreamToString(new InputStreamReader(input), endlMode); - } - - /** - * @param input | Input reader! - * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
- * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! - * - * @return Reader converted to string form! - * - * @throws IOException - * - * @since 1.3.2 - */ - public static String StreamToString(Reader input, int endlMode) throws IOException - { - String l; - StringBuilder sb = new StringBuilder(); - - BufferedReader r = new BufferedReader(input); - while ((l = r.readLine()) != null) - { - sb.append(l); - if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) - sb.append("\n"); - } - r.close(); - return sb.toString(); - } - - /* Reflect */ - - /** - * @param cls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.2.2 - */ - public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(null, cls, name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException - { - return InvokeFunc(obj, obj.getClass(), name, args); - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param objCls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException - { - Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); - if (result != null) - return result; - result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); - if (result == null) - LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); - return result; - } - - /** - * @param obj | The object the underlying method is invoked from! - * @param objCls | Class to invoke method from. - * @param name | Name of public static method to be called. - * @param argClasses | Classes of args. - * @param args | Arguments of method. Arguments should be certain if method is overloaded! - * - * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. - * - * @throws InvocationTargetException if called method throws and exception while calling! - * - * @since 1.3.5 - */ - public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException - { - try - { - Method method = objCls.getMethod(name, argClasses); - Object result = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : result; - } - catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) - { - for (Method method : objCls.getMethods()) - if (method.getName().equals(name)) - try - { - Object result = method.invoke(obj, args); - return method.getReturnType().equals(void.class) ? VOID : result; - } - catch (IllegalArgumentException e) - {} - catch (SecurityException | IllegalAccessException ex) - { - ex.printStackTrace(); - } - } - return null; - } - - - //Syntactical analyzes and fast string utility: - - /** - * @param obj | Object to clone. - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! - * - * @since 1.2.2 - */ - public static T Clone(T obj) - { - return Clone(obj, DataParser.REGISTRY, new Object[0], new Scope()); - } - - /** - * @param obj | Object to clone. - * @param parsersToUse | Parsers that will be used for cloning... - * @param converterArgs | Argument for {@link DataConverter#objToString(Object, Object...)}! - * @param parserArgs | Arguments for {@link ParserRegistry#parse(String, boolean, Class, Object...)}! - * - * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. - * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
- * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! - * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! Also note that certain objects such as primitive wrappers ({@link Integer}, {@link Float} etc...) will not be necessarily cloned since cloning them is not reasonable... - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Clone(T obj, Collection parsersToUse, Object[] converterArgs, Object... parserArgs) - { - if (obj == null) - return null; - if (obj.getClass() == Byte.class) - return (T) (Byte) ((byte) obj); // valueOf call... - if (obj.getClass() == Short.class) - return (T) (Short) ((short) obj); - if (obj.getClass() == Integer.class) - return (T) (Integer) ((int) obj); - if (obj.getClass() == Long.class) - return (T) (Long) ((long) obj); - if (obj.getClass() == Float.class) - return (T) (Float) ((float) obj); - if (obj.getClass() == Double.class) - return (T) (Double) ((double) obj); - if (obj.getClass() == Character.class) - return (T) (Character) ((char) obj); - if (obj.getClass() == Boolean.class) - return (T) (Boolean) ((boolean) obj); - if (obj.getClass() == String.class) - return (T) new String((String) obj); - - ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); - - Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); - if (cln != null && cln != VOID) - return (T) cln; - - if (obj instanceof Cloneable) - { - try - { - Method method = Object.class.getDeclaredMethod("clone"); - method.setAccessible(true); - return (T) method.invoke(obj); - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } - LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); - return obj; - } - - /** - * @param cls | Class to instantiate. - * - * @return New blank instance of required class created by calling shortest public constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.2.2 - */ - public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException - { - return Instantiate(cls, true); - } - - /** - * @param cls | Class to instantiate. - * @param publicOnly | If true, only public constructors will be used to create the object! - * - * @return New blank instance of required class created by calling shortest constructor with default values!
- * Note: Do not use this when your class contains final fields! - * - * @throws NoSuchMethodException if there is no public constructor! - * @throws InvocationTargetException if called constructor throws and exception! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException - { - try - { - Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); - if (!publicOnly) - cons.setAccessible(true); - return cons.newInstance(); - } - catch (Exception e) - { - try - { - Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); - if (cnstrs.length <= 0) - throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); - - for (int i = 1; i < cnstrs.length; i++) - { - if (!publicOnly) - cnstrs[0].setAccessible(true); - if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) - cnstrs[0] = cnstrs[i]; - } - - Object[] args = new Object[cnstrs[0].getParameterCount()]; - Class[] argTypes = cnstrs[0].getParameterTypes(); - for (int i = 0; i < cnstrs[0].getParameterCount(); i++) - { - if (argTypes[i] == byte.class) - args[i] = (byte) 0; - else if (argTypes[i] == short.class) - args[i] = (short) 0; - else if (argTypes[i] == int.class) - args[i] = 0; - else if (argTypes[i] == long.class) - args[i] = 0l; - else if ( argTypes[i] == float.class) - args[i] = 0.0f; - else if (argTypes[i] == double.class) - args[i] = 0.0; - else if (argTypes[i] == char.class) - args[i] = (char) 0; - else if (argTypes[i] == boolean.class) - args[i] = false; - else if (argTypes[i] == String.class) - args[i] = ""; - else - args[i] = null; - } - return (T) cnstrs[0].newInstance(args); - } - catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) - { - e2.printStackTrace(); - } - } - return null; - } - - /** - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.2.2 - */ - public static Class[] ToClasses(Object... objs) - { - return ToClasses(true, objs); - } - - /** - * @param unwrap | If the box types should be unwrapped to primitives... - * @param objs | Array of objects. - * - * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class - * - * @since 1.3.5 - */ - public static Class[] ToClasses(boolean unwrap, Object... objs) - { - Class[] classes = new Class[objs.length]; - if (unwrap) - { - for (int i = 0; i < classes.length; i++) - { - if (objs[i] == null) - classes[i] = Object.class; - else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) - classes[i] = byte.class; - else if (objs[i].getClass() == Short.class || objs[i] == Short.class) - classes[i] = short.class; - else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) - classes[i] = int.class; - else if (objs[i].getClass() == Long.class || objs[i] == Long.class) - classes[i] = long.class; - else if (objs[i].getClass() == Float.class || objs[i] == Float.class) - classes[i] = float.class; - else if (objs[i].getClass() == Double.class || objs[i] == Double.class) - classes[i] = double.class; - else if (objs[i].getClass() == Character.class || objs[i] == Character.class) - classes[i] = char.class; - else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) - classes[i] = boolean.class; - else if (objs[i] instanceof Class) - classes[i] = (Class) objs[i]; - else - classes[i] = objs[i].getClass(); - } - - return classes; - } - - for (int i = 0; i < classes.length; i++) - classes[i] = objs[i] == null ? Object.class : objs[i].getClass(); - return classes; - } - - /* Characters */ - - /** - * @param ch | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; - * - * @since 1.3.2 - */ - public static StringBuilder multilpy(char ch, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(ch); - return sb; - } - - /** - * @param str | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; - * - * @since 1.3.0 - */ - public static StringBuilder multilpy(CharSequence str, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(str); - return sb; - } - - /** - * @param s | String to split and check some syntax. - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} - * - * @since 1.0.0 - */ - public static String[] splitValues(String s, char... splitter) - { - return splitValues(s, 0, 2, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.0 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.5 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
- * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.8 - */ - public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - if (splitter.length <= 0 || limit == 1) - return new String[] {s}; -// -// if (isOneOf(s.charAt(0), splitter)) -// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); - - List result = new ArrayList<>(); - - int lastIndex = 0, len = s.length(); - for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) - { - int ch = s.charAt(i); - if (ch == '"') - { - do if (++i >= len) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); - while (s.charAt(i) != '"'); - } - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && s.charAt(i) != '"'); - } - } - else if (isOneOf(ch, splitBreaks)) - break; - else if (isOneOf(ch, splitter) && - (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) - { - String tok = s.substring(lastIndex, i).trim(); - if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) - { - result.add(tok); - lastIndex = i + 1; - - count++; - } - } - - oldCh = ch; - } - - result.add(s.substring(lastIndex, len).trim()); - return result.toArray(new String[0]); - } - - /** - * @param s | CharSequence to search! - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, char... oneOf) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) - { - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else if (isOneOf(ch, oneOf)) - { - if (firstIndex) - return from; - defaultReturn = from; - } - } - return defaultReturn; - } - - /** - * @param s | CharSequence to search! - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) - { - if (sequencesToFind.length < 1) - return defaultReturn; - - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else - { - findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) - { - CharSequence currentMatch; - if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) - { - int match = 1, lenToFind = currentMatch.length(); - for (int i = from+1; i < to && match < lenToFind; i++, match++) - if (s.charAt(i) != currentMatch.charAt(match)) - continue findMatch; - - if (match == lenToFind) - { - defaultReturn = from; - if (firstIndex) - return defaultReturn; - } - } - } - } - } - return defaultReturn; - } - - /** - * @param str | String to do replacements in! - * @param target | Target to replace! - * @param replacement | Replacement for target! - * - * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! - * - * @since 1.2.0 - */ - public static String fastReplace(String str, String target, CharSequence replacement) - { - int targetLength = target.length(); - if (targetLength == 0) - return str; - - int i1 = 0, i2 = str.indexOf(target); - if (i2 < 0) - return str; - - int len = str.length(); - StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); - do - { - sb.append(str, i1, i2).append(replacement); - i1 = i2 + targetLength; - i2 = str.indexOf(target, i1); - } while (i2 > 0); - - return sb.append(str, i1, len).toString(); - } - - /** - * @param ch | Char to compare! - * @param chars | Chars to match! - * - * @return True if inserted char (ch) is any of inserted chars! - * - * @since 1.3.0 - */ - public static boolean isOneOf(int ch, char... chars) - { - final int charsLen = chars.length; - for (int i = 0; i < charsLen; i++) - if (chars[i] == ch) - return true; - return false; - } - - /** - * @param str | Char sequence to search. - * @param oneOf | Chars to search for! - * - * @return {@link String#contains(CharSequence)} for char sequence! - * - * @since 1.3.0 - */ - public static boolean contains(CharSequence str, char... oneOf) - { - if (oneOf.length == 1) - { - for (int i = 0, len = str.length(); i < len; i++) - if (str.charAt(i) == oneOf[0]) - return true; - return false; - } - - for (int i = 0, len = str.length(); i < len; i++) - if (isOneOf(str.charAt(i), oneOf)) - return true; - return false; - } - - /** - * @param str | Source string to compare. - * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! - * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). - * @param to | The ending marking index, index where to end the comparing (exclusive, most likely {@code >= to <= str.length()}) - * - * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
- * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
- * Also sufficient length of both strings is not checked so adjust from and to accordingly. - * - * @since 1.3.8 - */ - public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) - { - for (; from < to; from++) - if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) - return false; - return true; - } - - /** - * @param str | String to display! - * @param pos | Position to display! - * - * @return String with displayed position by using » or ^ under it! - * Use for debugging or error printing! - * - * @since 1.3.2 - */ - public static String showPosInString(CharSequence str, int pos) - { - if (pos < 0) - return str.toString(); - - try - { - if (contains(str, ENDL)) - return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); - return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); - } - catch (IndexOutOfBoundsException e) - { - return str.toString(); - } - } - - /* Arrays */ - - /** - * @param sourceArray | Array to cast! - * @param toType | Type to cast array in to! - * - * @return Array object casted in to required type! - * - * @since 1.3.2 - */ - public static Object castArray(Object[] sourceArray, Class toType) - { - int len; - Object arr = Array.newInstance(ToClasses(toType)[0], len = sourceArray.length); - for (int i = 0; i < len; i++) - Array.set(arr, i, sourceArray[i]); - return arr; - } - - /** - * @param arr1 | Object one that might be array! - * @param arr2 | Object two that might be array! - * - * @return New array consisting of array 1 and array 2! - * - * @throws IllegalArgumentException if object one is not an array! - * - * @since 1.3.2 - */ - public static Object[] mergeArrays(Object arr1, Object arr2) - { - Object[] array1 = fromAmbiguousArray(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguousArray(arr2) : new Object[] { arr2 }; - Object[] result = Arrays.copyOf(array1, array1.length + array2.length); - System.arraycopy(array2, 0, result, array1.length, array2.length); - return result; - } - - /** - * @param array | Object that might be array! - * - * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! - * - * @throws IllegalArgumentException if the specified object is not an array! - * - * @since 1.3.2 (since 1.3.8 moved from ArrayConverter) - */ - public static Object[] fromAmbiguousArray(Object array) - { - if (array instanceof Object[]) - return (Object[]) array; - - int len = Array.getLength(array); // Arr of primitives cos Java... - Object[] arr = new Object[len]; - for (int i = 0; i < len; i++) - arr[i] = Array.get(array, i); - return arr; - } - - /* Others... */ - - /** - * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! - * - * @param serializer | Serializer to post. - * @param conn | Http connection to use! - * - * @throws IOException if posting failed! - * - * @since 1.3.5 - */ - public static void post(Serializer serializer, HttpURLConnection conn) throws IOException - { - StringBuilder postData = new StringBuilder(); - for (Map.Entry param : serializer.varEntrySet()) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); - } - - for (Object param : serializer) - { - if (postData.length() != 0) - postData.append('&'); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); - } - - byte[] postDataBytes = postData.toString().getBytes("UTF-8"); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); - conn.setDoOutput(true); - conn.getOutputStream().write(postDataBytes); - } +package org.ugp.serialx.utils; + +import static org.ugp.serialx.converters.DataParser.VOID; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Array; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.HttpURLConnection; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.protocols.SerializationProtocol; + +/** + * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection. + * + * @author PETO + * + * @since 1.3.8 + */ +public final class Utils { + private Utils() {} + + /** + * {@link System#lineSeparator()} + * + * @since 1.3.9 + */ + public static final char[] ENDL = System.lineSeparator().toCharArray(); + + /** + * @param f | Source file. + * + * @return All lines from source file as string. + * @throws IOException + * + * @since 1.1.5 + */ + public static String LoadFileToString(File f) throws IOException + { + return LoadFileToString(f, 1); + } + + /** + * @param f | Source file. + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Content of file as string. + * @throws IOException + * + * @since 1.2.0 + */ + public static String LoadFileToString(File f, int endlMode) throws IOException + { + return StreamToString(new FileReader(f), endlMode); + } + + /** + * @param input | Input stream to read to string! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.5 + */ + public static String StreamToString(InputStream input, int endlMode) throws IOException + { + return StreamToString(new InputStreamReader(input), endlMode); + } + + /** + * @param input | Input reader! + * @param endlMode | 0 = no line brakes, 1 = always line brakes, 2 = line break only when contains with "//"!
+ * Note: You almost always want endlMode on 1. So thats why you should use {@link #LoadFileToString(File)} which is doing this automatically! + * + * @return Reader converted to string form! + * + * @throws IOException + * + * @since 1.3.2 + */ + public static String StreamToString(Reader input, int endlMode) throws IOException + { + String l; + StringBuilder sb = new StringBuilder(); + + BufferedReader r = new BufferedReader(input); + while ((l = r.readLine()) != null) + { + sb.append(l); + if (endlMode == 1 || (endlMode > 1 && l.contains("//"))) + sb.append("\n"); + } + r.close(); + return sb.toString(); + } + + /* Reflect */ + + /** + * @param cls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.2.2 + */ + public static Object InvokeStaticFunc(Class cls, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(null, cls, name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, String name, Object... args) throws InvocationTargetException + { + return InvokeFunc(obj, obj.getClass(), name, args); + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param objCls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Object... args) throws InvocationTargetException + { + Object result = InvokeFunc(obj, objCls, name, ToClasses(args), args); + if (result != null) + return result; + result = InvokeFunc(obj, objCls, name, ToClasses(false, args), args); + if (result == null) + LogProvider.instance.logErr("Unable to call function \"" + name + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied or function does not exist in required class!", null); + return result; + } + + /** + * @param obj | The object the underlying method is invoked from! + * @param objCls | Class to invoke method from. + * @param name | Name of public static method to be called. + * @param argClasses | Classes of args. + * @param args | Arguments of method. Arguments should be certain if method is overloaded! + * + * @return The returned result of called method or {@link #VOID} if return type of method is void. If something when wrong you will be notified and null will be returned. + * + * @throws InvocationTargetException if called method throws and exception while calling! + * + * @since 1.3.5 + */ + public static Object InvokeFunc(Object obj, Class objCls, String name, Class[] argClasses, Object... args) throws InvocationTargetException + { + try + { + Method method = objCls.getMethod(name, argClasses); + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; + } + catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException find) + { + for (Method method : objCls.getMethods()) + if (method.getName().equals(name)) + try + { + Object result = method.invoke(obj, args); + return method.getReturnType().equals(void.class) ? VOID : result; + } + catch (IllegalArgumentException e) + {} + catch (SecurityException | IllegalAccessException ex) + { + ex.printStackTrace(); + } + } + return null; + } + + + //Syntactical analyzes and fast string utility: + + /** + * @param obj | Object to clone. + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! + * + * @since 1.2.2 + */ + public static T Clone(T obj) + { + return Clone(obj, DataParser.REGISTRY, new Object[0], new Scope()); + } + + /** + * @param obj | Object to clone. + * @param parsersToUse | Parsers that will be used for cloning... + * @param converterArgs | Argument for {@link DataConverter#objToString(Object, Object...)}! + * @param parserArgs | Arguments for {@link ParserRegistry#parse(String, boolean, Class, Object...)}! + * + * @return Cloned object using {@link DataParser}, {@link DataConverter} and {@link SerializationProtocol} or the same object as inserted one if cloning is not possible, for instance when protocol was not found and object is not instance of {@link Cloneable}. + * This clone function will always prioritized the Protocol variation, regular cloning is used only when there is no protocol registered or exception occurs.
+ * Note: If there are protocols to serialize inserted object and all its sub-objects and variables then this clone will be absolute deep copy, meaning that making any changes to this cloned object or to its variables will not affect original one in any way! + * But keep in mind that this clone is absolute hoverer, based on protocols used, it does not need to be an 100% copy! Also note that certain objects such as primitive wrappers ({@link Integer}, {@link Float} etc...) will not be necessarily cloned since cloning them is not reasonable... + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Clone(T obj, Collection parsersToUse, Object[] converterArgs, Object... parserArgs) + { + if (obj == null) + return null; + if (obj.getClass() == Byte.class) + return (T) (Byte) ((byte) obj); // valueOf call... + if (obj.getClass() == Short.class) + return (T) (Short) ((short) obj); + if (obj.getClass() == Integer.class) + return (T) (Integer) ((int) obj); + if (obj.getClass() == Long.class) + return (T) (Long) ((long) obj); + if (obj.getClass() == Float.class) + return (T) (Float) ((float) obj); + if (obj.getClass() == Double.class) + return (T) (Double) ((double) obj); + if (obj.getClass() == Character.class) + return (T) (Character) ((char) obj); + if (obj.getClass() == Boolean.class) + return (T) (Boolean) ((boolean) obj); + if (obj.getClass() == String.class) + return (T) new String((String) obj); + + ParserRegistry parsers = parsersToUse instanceof ParserRegistry ? (ParserRegistry) parsersToUse : new ParserRegistry(parsersToUse); + + Object cln = parsers.parse(parsers.toString(obj, converterArgs).toString(), parserArgs); + if (cln != null && cln != VOID) + return (T) cln; + + if (obj instanceof Cloneable) + { + try + { + Method method = Object.class.getDeclaredMethod("clone"); + method.setAccessible(true); + return (T) method.invoke(obj); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + } + LogProvider.instance.logErr("Unable to clone " + obj.getClass() + ": " + obj, null); + return obj; + } + + /** + * @param cls | Class to instantiate. + * + * @return New blank instance of required class created by calling shortest public constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.2.2 + */ + public static T Instantiate(Class cls) throws NoSuchMethodException, InvocationTargetException + { + return Instantiate(cls, true); + } + + /** + * @param cls | Class to instantiate. + * @param publicOnly | If true, only public constructors will be used to create the object! + * + * @return New blank instance of required class created by calling shortest constructor with default values!
+ * Note: Do not use this when your class contains final fields! + * + * @throws NoSuchMethodException if there is no public constructor! + * @throws InvocationTargetException if called constructor throws and exception! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public static T Instantiate(Class cls, boolean publicOnly) throws NoSuchMethodException, InvocationTargetException + { + try + { + Constructor cons = publicOnly ? cls.getConstructor() : cls.getDeclaredConstructor(); + if (!publicOnly) + cons.setAccessible(true); + return cons.newInstance(); + } + catch (Exception e) + { + try + { + Constructor[] cnstrs = publicOnly ? cls.getConstructors() : cls.getDeclaredConstructors(); + if (cnstrs.length <= 0) + throw new NoSuchMethodException("No public constructors in class " + cls.getName() + "!"); + + for (int i = 1; i < cnstrs.length; i++) + { + if (!publicOnly) + cnstrs[0].setAccessible(true); + if (cnstrs[i].getParameterCount() < cnstrs[0].getParameterCount()) + cnstrs[0] = cnstrs[i]; + } + + Object[] args = new Object[cnstrs[0].getParameterCount()]; + Class[] argTypes = cnstrs[0].getParameterTypes(); + for (int i = 0; i < cnstrs[0].getParameterCount(); i++) + { + if (argTypes[i] == byte.class) + args[i] = (byte) 0; + else if (argTypes[i] == short.class) + args[i] = (short) 0; + else if (argTypes[i] == int.class) + args[i] = 0; + else if (argTypes[i] == long.class) + args[i] = 0l; + else if ( argTypes[i] == float.class) + args[i] = 0.0f; + else if (argTypes[i] == double.class) + args[i] = 0.0; + else if (argTypes[i] == char.class) + args[i] = (char) 0; + else if (argTypes[i] == boolean.class) + args[i] = false; + else if (argTypes[i] == String.class) + args[i] = ""; + else + args[i] = null; + } + return (T) cnstrs[0].newInstance(args); + } + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | SecurityException e2) + { + e2.printStackTrace(); + } + } + return null; + } + + /** + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.2.2 + */ + public static Class[] ToClasses(Object... objs) + { + return ToClasses(true, objs); + } + + /** + * @param unwrap | If the box types should be unwrapped to primitives... + * @param objs | Array of objects. + * + * @return Array of inserted objects class types. Wrapper types of primitive values will be converted to primitive types! For instance: Integer.class -> int.class + * + * @since 1.3.5 + */ + public static Class[] ToClasses(boolean unwrap, Object... objs) + { + Class[] classes = new Class[objs.length]; + if (unwrap) + { + for (int i = 0; i < classes.length; i++) + { + if (objs[i] == null) + classes[i] = Object.class; + else if (objs[i].getClass() == Byte.class || objs[i] == Byte.class) + classes[i] = byte.class; + else if (objs[i].getClass() == Short.class || objs[i] == Short.class) + classes[i] = short.class; + else if (objs[i].getClass() == Integer.class || objs[i] == Integer.class) + classes[i] = int.class; + else if (objs[i].getClass() == Long.class || objs[i] == Long.class) + classes[i] = long.class; + else if (objs[i].getClass() == Float.class || objs[i] == Float.class) + classes[i] = float.class; + else if (objs[i].getClass() == Double.class || objs[i] == Double.class) + classes[i] = double.class; + else if (objs[i].getClass() == Character.class || objs[i] == Character.class) + classes[i] = char.class; + else if (objs[i].getClass() == Boolean.class || objs[i] == Boolean.class) + classes[i] = boolean.class; + else if (objs[i] instanceof Class) + classes[i] = (Class) objs[i]; + else + classes[i] = objs[i].getClass(); + } + + return classes; + } + + for (int i = 0; i < classes.length; i++) + classes[i] = objs[i] == null ? Object.class : objs[i].getClass(); + return classes; + } + + /* Characters */ + + /** + * @param ch | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; + * + * @since 1.3.2 + */ + public static StringBuilder multilpy(char ch, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(ch); + return sb; + } + + /** + * @param str | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; + * + * @since 1.3.0 + */ + public static StringBuilder multilpy(CharSequence str, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(str); + return sb; + } + + /** + * @param s | String to split and check some syntax. + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} + * + * @since 1.0.0 + */ + public static String[] splitValues(String s, char... splitter) + { + return splitValues(s, 0, 2, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.0 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.5 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
+ * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.8 + */ + public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + if (splitter.length <= 0 || limit == 1) + return new String[] {s}; +// +// if (isOneOf(s.charAt(0), splitter)) +// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); + + List result = new ArrayList<>(); + + int lastIndex = 0, len = s.length(); + for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) + { + int ch = s.charAt(i); + if (ch == '"') + { + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + while (s.charAt(i) != '"'); + } + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + } + } + else if (isOneOf(ch, splitBreaks)) + break; + else if (isOneOf(ch, splitter) && + (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + String tok = s.substring(lastIndex, i).trim(); + if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) + { + result.add(tok); + lastIndex = i + 1; + + count++; + } + } + + oldCh = ch; + } + + result.add(s.substring(lastIndex, len).trim()); + return result.toArray(new String[0]); + } + + /** + * @param s | CharSequence to search! + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, char... oneOf) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) + { + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else if (isOneOf(ch, oneOf)) + { + if (firstIndex) + return from; + defaultReturn = from; + } + } + return defaultReturn; + } + + /** + * @param s | CharSequence to search! + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) + { + if (sequencesToFind.length < 1) + return defaultReturn; + + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else + { + findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) + { + CharSequence currentMatch; + if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) + { + int match = 1, lenToFind = currentMatch.length(); + for (int i = from+1; i < to && match < lenToFind; i++, match++) + if (s.charAt(i) != currentMatch.charAt(match)) + continue findMatch; + + if (match == lenToFind) + { + defaultReturn = from; + if (firstIndex) + return defaultReturn; + } + } + } + } + } + return defaultReturn; + } + + /** + * @param str | String to do replacements in! + * @param target | Target to replace! + * @param replacement | Replacement for target! + * + * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! + * + * @since 1.2.0 + */ + public static String fastReplace(String str, String target, CharSequence replacement) + { + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + int len = str.length(); + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, len).toString(); + } + + /** + * @param ch | Char to compare! + * @param chars | Chars to match! + * + * @return True if inserted char (ch) is any of inserted chars! + * + * @since 1.3.0 + */ + public static boolean isOneOf(int ch, char... chars) + { + final int charsLen = chars.length; + for (int i = 0; i < charsLen; i++) + if (chars[i] == ch) + return true; + return false; + } + + /** + * @param str | Char sequence to search. + * @param oneOf | Chars to search for! + * + * @return {@link String#contains(CharSequence)} for char sequence! + * + * @since 1.3.0 + */ + public static boolean contains(CharSequence str, char... oneOf) + { + if (oneOf.length == 1) + { + for (int i = 0, len = str.length(); i < len; i++) + if (str.charAt(i) == oneOf[0]) + return true; + return false; + } + + for (int i = 0, len = str.length(); i < len; i++) + if (isOneOf(str.charAt(i), oneOf)) + return true; + return false; + } + + /** + * @param str | Source string to compare. + * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! + * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). + * @param to | The ending marking index, index where to end the comparing (exclusive, most likely {@code >= to <= str.length()}) + * + * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
+ * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
+ * Also sufficient length of both strings is not checked so adjust from and to accordingly. + * + * @since 1.3.8 + */ + public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) + { + for (; from < to; from++) + if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) + return false; + return true; + } + + /** + * @param str | String to display! + * @param pos | Position to display! + * + * @return String with displayed position by using » or ^ under it! + * Use for debugging or error printing! + * + * @since 1.3.2 + */ + public static String showPosInString(CharSequence str, int pos) + { + if (pos < 0) + return str.toString(); + + try + { + if (contains(str, ENDL)) + return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); + return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); + } + catch (IndexOutOfBoundsException e) + { + return str.toString(); + } + } + + /* Arrays */ + + /** + * @param sourceArray | Array to cast! + * @param toType | Type to cast array in to! + * + * @return Array object casted in to required type! + * + * @since 1.3.2 + */ + public static Object castArray(Object[] sourceArray, Class toType) + { + int len; + Object arr = Array.newInstance(ToClasses(toType)[0], len = sourceArray.length); + for (int i = 0; i < len; i++) + Array.set(arr, i, sourceArray[i]); + return arr; + } + + /** + * @param arr1 | Object one that might be array! + * @param arr2 | Object two that might be array! + * + * @return New array consisting of array 1 and array 2! + * + * @throws IllegalArgumentException if object one is not an array! + * + * @since 1.3.2 + */ + public static Object[] mergeArrays(Object arr1, Object arr2) + { + Object[] array1 = fromAmbiguousArray(arr1), array2 = arr2.getClass().isArray() ? fromAmbiguousArray(arr2) : new Object[] { arr2 }; + Object[] result = Arrays.copyOf(array1, array1.length + array2.length); + System.arraycopy(array2, 0, result, array1.length, array2.length); + return result; + } + + /** + * @param array | Object that might be array! + * + * @return Object transformed in to primitive array! If array is already an instance of primitive array then it will be simply returned! + * + * @throws IllegalArgumentException if the specified object is not an array! + * + * @since 1.3.2 (since 1.3.8 moved from ArrayConverter) + */ + public static Object[] fromAmbiguousArray(Object array) + { + if (array instanceof Object[]) + return (Object[]) array; + + int len = Array.getLength(array); // Arr of primitives cos Java... + Object[] arr = new Object[len]; + for (int i = 0; i < len; i++) + arr[i] = Array.get(array, i); + return arr; + } + + /* Others... */ + + /** + * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! + * + * @param serializer | Serializer to post. + * @param conn | Http connection to use! + * + * @throws IOException if posting failed! + * + * @since 1.3.5 + */ + public static void post(Serializer serializer, HttpURLConnection conn) throws IOException + { + StringBuilder postData = new StringBuilder(); + for (Map.Entry param : serializer.varEntrySet()) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); + } + + for (Object param : serializer) + { + if (postData.length() != 0) + postData.append('&'); + postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); + } + + byte[] postDataBytes = postData.toString().getBytes("UTF-8"); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); + conn.setDoOutput(true); + conn.getOutputStream().write(postDataBytes); + } } \ No newline at end of file diff --git a/SerialX-devtools/pom.xml b/SerialX-devtools/pom.xml index a6eba2a..dee83e5 100644 --- a/SerialX-devtools/pom.xml +++ b/SerialX-devtools/pom.xml @@ -1,25 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-devtools - 4.0.0-SNAPSHOT - - SerialX devtools - Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. - - - - org.ugp.serialx - serialx-core - 4.0.0-SNAPSHOT - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-devtools + 4.0.0-SNAPSHOT + + SerialX devtools + Tools for debugging, mainly for Parser/Converter API. It is intended for DSL developers and people who want to add their own data formats. + + + + org.ugp.serialx + serialx-core + 4.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java index 37b5116..c8f3ba3 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/DebugParserRegistry.java @@ -1,180 +1,180 @@ -package org.ugp.serialx.devtools; - -import java.io.IOException; -import java.util.Map; -import java.util.TreeMap; - -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.utils.LogProvider; - -/** - * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! - * - * @author PETO - * - * @since 1.3.5 - */ -public class DebugParserRegistry extends ParserRegistry -{ - private static final long serialVersionUID = 3445967263611388142L; - - protected Map iterationStackTrace = new TreeMap<>(); - - public DebugParserRegistry(ParserRegistry registry) - { - super(registry); - resetCache(registry.getParsingCache(), registry.getConverterCache()); - } - - @Override - public DebugParserRegistry clone() - { - return clone(true); - } - - /** - * @param copyStackTrace | If true, cloned object will share the same iterationStackTrace with original, otherwise it will get new empty one. - * - * @return Clone of this {@link DebugParserRegistry} - * - * @since 1.3.8 - */ - public DebugParserRegistry clone(boolean copyStackTrace) - { - DebugParserRegistry reg = new DebugParserRegistry(this); - if (copyStackTrace) - reg.iterationStackTrace = this.iterationStackTrace; - return reg; - } - - @Override - public Appendable toString(Appendable source, Object obj, Object... args) throws IOException - { - int iterationIndex = 0; - if (args.length > 99 && args[99] instanceof Integer) - { - iterationIndex = (int) args[99]; - args[99] = iterationIndex + 1; - } - - CharSequence str = null; - if (convertingCache != null) - for (int i = 0; i < convertingCache.length; i++) - { - DataConverter converter = convertingCache[i]; - if (converter != null) - { - double t0 = System.nanoTime(); - str = (CharSequence) converter.toString(new StringBuilder(), this, obj, args); - double t = System.nanoTime(); - if (str != SerializationDebugger.CONTINUE) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + converter + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return source.append(str); - } - } - } - - for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (parser instanceof DataConverter) - { - double t0 = System.nanoTime(); - str = (CharSequence) ((DataConverter) parser).toString(new StringBuilder(), this, obj, args); - double t = System.nanoTime(); - if(str != SerializationDebugger.CONTINUE) - { - if (convertingCache != null && i < convertingCache.length) - convertingCache[i] = (DataConverter) parser; - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); - return source.append(str); - } - } - } - - LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); - return null; - } - - @Override - public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) - { - int iterationIndex = 0; - if (args.length > 99 && args[99] instanceof Integer) - { - iterationIndex = (int) args[99]; - args[99] = iterationIndex + 1; - } - - Object obj = null; - if (parsingCache != null) - for (int i = 0; i < parsingCache.length; i++) - { - DataParser parser = parsingCache[i]; - if (parser != null && (ignore == null || ignore != parser.getClass())) - { -// try -// { - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != SerializationDebugger.CONTINUE) - { - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); - return obj; - } -// } -// catch (Exception ex) -// { -// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " (from cache)\n>>\t\"" + str + "\"\tthrew\t" + ex); -// return null; -// } - } - } - - for (int i = 0, size = size(); i < size; i++) - { - DataParser parser = get(i); - if (ignore != null && ignore == parser.getClass()) - continue; - -// try -// { - double t0 = System.nanoTime(); - obj = parser.parse(this, str, args); - double t = System.nanoTime(); - if (obj != SerializationDebugger.CONTINUE) - { - if (parsingCache != null && i < parsingCache.length) - parsingCache[i] = parser; - iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); - return obj; - } -// } -// catch (Exception ex) -// { -// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + "\n>>\t\"" + str + "\"\tthrew\t" + ex); -// return null; -// } - } - - if (returnAsStringIfNotFound) - return str; - - LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); - return null; - } - - /** - * @return Ordered map of registry iterations generated by using it during parsing or converting! - * - * @since 1.3.5 - */ - public Map getRegistryIterationStackTrace() - { - return iterationStackTrace; - } +package org.ugp.serialx.devtools; + +import java.io.IOException; +import java.util.Map; +import java.util.TreeMap; + +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.utils.LogProvider; + +/** + * Special {@link ParserRegistry} that keeps track of its actions! Use only for debugging! + * + * @author PETO + * + * @since 1.3.5 + */ +public class DebugParserRegistry extends ParserRegistry +{ + private static final long serialVersionUID = 3445967263611388142L; + + protected Map iterationStackTrace = new TreeMap<>(); + + public DebugParserRegistry(ParserRegistry registry) + { + super(registry); + resetCache(registry.getParsingCache(), registry.getConverterCache()); + } + + @Override + public DebugParserRegistry clone() + { + return clone(true); + } + + /** + * @param copyStackTrace | If true, cloned object will share the same iterationStackTrace with original, otherwise it will get new empty one. + * + * @return Clone of this {@link DebugParserRegistry} + * + * @since 1.3.8 + */ + public DebugParserRegistry clone(boolean copyStackTrace) + { + DebugParserRegistry reg = new DebugParserRegistry(this); + if (copyStackTrace) + reg.iterationStackTrace = this.iterationStackTrace; + return reg; + } + + @Override + public Appendable toString(Appendable source, Object obj, Object... args) throws IOException + { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + CharSequence str = null; + if (convertingCache != null) + for (int i = 0; i < convertingCache.length; i++) + { + DataConverter converter = convertingCache[i]; + if (converter != null) + { + double t0 = System.nanoTime(); + str = (CharSequence) converter.toString(new StringBuilder(), this, obj, args); + double t = System.nanoTime(); + if (str != SerializationDebugger.CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + converter + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return source.append(str); + } + } + } + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (parser instanceof DataConverter) + { + double t0 = System.nanoTime(); + str = (CharSequence) ((DataConverter) parser).toString(new StringBuilder(), this, obj, args); + double t = System.nanoTime(); + if(str != SerializationDebugger.CONTINUE) + { + if (convertingCache != null && i < convertingCache.length) + convertingCache[i] = (DataConverter) parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t" + SerializationDebugger.toStringAndCls(obj) + "\t -->\t\"" + str + "\""); + return source.append(str); + } + } + } + + LogProvider.instance.logErr("Unable to convert \"" + obj == null ? "null" : obj.getClass().getName() + "\" to string because none of registered converters were aplicable for this object!", null); + return null; + } + + @Override + public Object parse(String str, boolean returnAsStringIfNotFound, Class ignore, Object... args) + { + int iterationIndex = 0; + if (args.length > 99 && args[99] instanceof Integer) + { + iterationIndex = (int) args[99]; + args[99] = iterationIndex + 1; + } + + Object obj = null; + if (parsingCache != null) + for (int i = 0; i < parsingCache.length; i++) + { + DataParser parser = parsingCache[i]; + if (parser != null && (ignore == null || ignore != parser.getClass())) + { +// try +// { + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms (from cache)\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } +// } +// catch (Exception ex) +// { +// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " (from cache)\n>>\t\"" + str + "\"\tthrew\t" + ex); +// return null; +// } + } + } + + for (int i = 0, size = size(); i < size; i++) + { + DataParser parser = get(i); + if (ignore != null && ignore == parser.getClass()) + continue; + +// try +// { + double t0 = System.nanoTime(); + obj = parser.parse(this, str, args); + double t = System.nanoTime(); + if (obj != SerializationDebugger.CONTINUE) + { + if (parsingCache != null && i < parsingCache.length) + parsingCache[i] = parser; + iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + " " + (t-t0)/1000000 + "ms\n>>\t\"" + str + "\"\t -->\t" + SerializationDebugger.toStringAndCls(obj)); + return obj; + } +// } +// catch (Exception ex) +// { +// iterationStackTrace.put(iterationIndex, "[" + i + "] " + parser + "\n>>\t\"" + str + "\"\tthrew\t" + ex); +// return null; +// } + } + + if (returnAsStringIfNotFound) + return str; + + LogProvider.instance.logErr("Unable to parse \"" + str + "\" because none of registred parsers were suitable!", null); + return null; + } + + /** + * @return Ordered map of registry iterations generated by using it during parsing or converting! + * + * @since 1.3.5 + */ + public Map getRegistryIterationStackTrace() + { + return iterationStackTrace; + } } \ No newline at end of file diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index bd2dc59..2e57938 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -1,288 +1,288 @@ -package org.ugp.serialx.devtools; - -import static org.ugp.serialx.utils.Utils.multilpy; - -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.Registry; - -/** - * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
- * During parsing, type __debug or __debug_yourObject into your code!
- * During converting/serializing, serialize your object using {@link DebugWrapper} with your object as argument! - * - * @see SerializationDebugger#debug(Serializer) - * - * @author PETO - * - * @since 1.3.5 - */ -public class SerializationDebugger implements DataConverter -{ - public static final String DEBUG_MARK = new String("__debug"); - - /** - * Output object that will be used for logging... - * If null, it will be set automatically! - * - * @since 1.3.8 - */ - public static PrintWriter out; - - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (str.toLowerCase().startsWith(DEBUG_MARK)) - try - { - return printDebugs(null, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); - } - catch (IOException e) - { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof DebugWrapper) - { - printDebugs(source, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), ((DebugWrapper) obj).obj, null, args); - return source; - } - return CONTINUE; - } - - /** - * Print and return debug results of parsing or converting! - * - * @return Parsed object or object converted to string! - * - * @since 1.3.5 - */ - public Object printDebugs(Appendable source, DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) throws IOException - { - if (out == null) - out = new PrintWriter(System.err); - - String action = objToSerialize == null && strToParse != null ? "Parsing" : "Converting"; - out.println("--------------------------------------------- " + action + " Debug ---------------------------------------------"); - if (args == null) - out.println("------- Available args (args): none (args = null)!"); - else - print(out, "------- Available args (args):", Arrays.asList(args), 0); - - if (myHomeRegistry == null) - out.println("\n------- Available parsers (myHomeRegistry: null): none!"); - else - print(out, "\n------- Available parsers (myHomeRegistry: " + myHomeRegistry.getClass().getName() + "):", myHomeRegistry, 0); - - if (strToParse != null && (strToParse = strToParse.substring(DEBUG_MARK.length())).length() > 0 && (strToParse = strToParse.substring(1)).length() > 0) - { - if (args.length < 100) - { - myHomeRegistry.getRegistryIterationStackTrace().clear(); - args = Arrays.copyOf(args, 100); - args[99] = 0; - } - else if (args[99] instanceof Integer && (int) args[99] > 0) - { - myHomeRegistry = myHomeRegistry.clone(false); - } - - double t0 = System.nanoTime(); - objToSerialize = myHomeRegistry.parse(strToParse, args); - double t = System.nanoTime(); - - printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", " (after process)"); - print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); - out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); - out.println("String \"" + strToParse + "\" was parsed into:\n\t" + toStringAndCls(objToSerialize)); - out.println("\n"); - - out.flush(); - return objToSerialize; - } - - if (objToSerialize != null) - { - if (args.length < 100) - { - myHomeRegistry.getRegistryIterationStackTrace().clear(); - args = Arrays.copyOf(args, 100); - args[99] = 0; - } - else if (args[99] instanceof Integer && (int) args[99] > 0) - { - myHomeRegistry = myHomeRegistry.clone(false); - } - - double t0 = System.nanoTime(); - strToParse = myHomeRegistry.toString(objToSerialize, args).toString(); - double t = System.nanoTime(); - - printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", " (after process)"); - print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); - out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); - out.println("Object " + toStringAndCls(objToSerialize) + " was converted to string:\n" + (strToParse.contains("\n") ? strToParse : "\t" + strToParse)); - out.println("\n"); - - out.flush(); - return source.append(strToParse); - } - - printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", ""); - printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", ""); - - out.println("\n--------------------------------------------- No Results ---------------------------------------------"); - if (myHomeRegistry.getParsingCache() != null && myHomeRegistry.getParsingCache().length > 0 || myHomeRegistry.getConverterCache() != null && myHomeRegistry.getConverterCache().length > 0) - out.println("If this is not the expected outcome you can try not using ParserRegistry caching or try to pre-cache some parsers!"); - out.println("\n"); - - out.flush(); - return VOID; - } - - /** - * Helper method for printing contents of {@link ParserRegistry#getParsingCache()}. - * - * @since 1.3.8 - */ - public static void printCacheInfo(PrintWriter out, DataParser[] cache, String cacheType, String additional) - { - if (cache == null) - out.println("\n------- Current " + cacheType + " cache" + additional + ": null (none)"); - else - print(out, "\n------- Current " + cacheType + " cache" + additional + ":", Arrays.asList(cache), 0); - } - - /** - * @param serializer | Serializer to debug! - * - * @return Serializer capable of debugging its serialization and deserialization! - * - * @since 1.3.5 - */ - public static T debug(T serializer) - { - return debug(serializer, new SerializationDebugger()); - } - - /** - * @param serializer | Serializer to debug! - * @param debugger | Specific debugger to use! - * - * @return Serializer capable of debugging its serialization and deserialization! - * - * @since 1.3.5 - */ - public static T debug(T serializer, SerializationDebugger debugger) - { - serializer.getParsers().add(0, debugger); - serializer.setParsers(new DebugParserRegistry(serializer.getParsers())); - return serializer; - } - - /** - * @param objToSerializeAndDebug | Object you want to serialize and see the debug of serialization! - * - * @return Object wrapped for debugger to debug! - * - * @since 1.3.5 - */ - public static DebugWrapper wrapForDebug(Object objToSerializeAndDebug) - { - return new DebugWrapper(objToSerializeAndDebug); - } - - /** - * @return obj + " (" + obj.getClass().getName() + ")" - * Note: Used internally by debugger! - * - * @since 1.3.5 - */ - public static String toStringAndCls(Object obj) - { - if (obj == null) - return "null"; - else - return obj + " (" + obj.getClass().getName() + ")"; - } - - /** - * This will print list into console in somewhat more readable form with tabs and introduction text! - * - * @since 1.3.5 - */ - public static void print(PrintWriter out, String text, List objs, int tabs) - { - out.println(text); - for (int i = 0, i2 = 0; i < objs.size(); i++) - { - Object o = objs.get(i); - String strTbs = multilpy('\t', tabs).toString(); - if (o instanceof List) - print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); - else if (o instanceof Map) - print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); - else - out.println(multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); - } - } - - /** - * This will print map into console in somewhat more readable form with tabs and introduction text! - * - * @since 1.3.5 - */ - public static void print(PrintWriter out, String text, Map map, int tabs) - { - out.println(text); - for (Entry entry : map.entrySet()) - { - Object o = entry.getValue(); - String strTbs = multilpy('\t', tabs).toString(); - if (o instanceof List) - print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); - else if (o instanceof Map) - print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); - else - out.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); - } - } - - /** - * Use this during converting/serializing! - * - * @author PETO - * - * @since 1.3.5 - * - * @see SerializationDebugger - */ - protected static class DebugWrapper - { - public final Object obj; - - /** - * @param yourObject | Your object to serialize in debug mode! - * - * @since 1.3.5 - */ - public DebugWrapper(Object yourObject) - { - obj = yourObject; - } - } +package org.ugp.serialx.devtools; + +import static org.ugp.serialx.utils.Utils.multilpy; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.Registry; + +/** + * Use this for debugging during parsing and converting by adding new instance of it into your parser {@link Registry} or in case of {@link Serializer} use !
+ * During parsing, type __debug or __debug_yourObject into your code!
+ * During converting/serializing, serialize your object using {@link DebugWrapper} with your object as argument! + * + * @see SerializationDebugger#debug(Serializer) + * + * @author PETO + * + * @since 1.3.5 + */ +public class SerializationDebugger implements DataConverter +{ + public static final String DEBUG_MARK = new String("__debug"); + + /** + * Output object that will be used for logging... + * If null, it will be set automatically! + * + * @since 1.3.8 + */ + public static PrintWriter out; + + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.toLowerCase().startsWith(DEBUG_MARK)) + try + { + return printDebugs(null, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), null, str, args); + } + catch (IOException e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof DebugWrapper) + { + printDebugs(source, myHomeRegistry instanceof DebugParserRegistry ? (DebugParserRegistry) myHomeRegistry : new DebugParserRegistry(myHomeRegistry), ((DebugWrapper) obj).obj, null, args); + return source; + } + return CONTINUE; + } + + /** + * Print and return debug results of parsing or converting! + * + * @return Parsed object or object converted to string! + * + * @since 1.3.5 + */ + public Object printDebugs(Appendable source, DebugParserRegistry myHomeRegistry, Object objToSerialize, String strToParse, Object... args) throws IOException + { + if (out == null) + out = new PrintWriter(System.err); + + String action = objToSerialize == null && strToParse != null ? "Parsing" : "Converting"; + out.println("--------------------------------------------- " + action + " Debug ---------------------------------------------"); + if (args == null) + out.println("------- Available args (args): none (args = null)!"); + else + print(out, "------- Available args (args):", Arrays.asList(args), 0); + + if (myHomeRegistry == null) + out.println("\n------- Available parsers (myHomeRegistry: null): none!"); + else + print(out, "\n------- Available parsers (myHomeRegistry: " + myHomeRegistry.getClass().getName() + "):", myHomeRegistry, 0); + + if (strToParse != null && (strToParse = strToParse.substring(DEBUG_MARK.length())).length() > 0 && (strToParse = strToParse.substring(1)).length() > 0) + { + if (args.length < 100) + { + myHomeRegistry.getRegistryIterationStackTrace().clear(); + args = Arrays.copyOf(args, 100); + args[99] = 0; + } + else if (args[99] instanceof Integer && (int) args[99] > 0) + { + myHomeRegistry = myHomeRegistry.clone(false); + } + + double t0 = System.nanoTime(); + objToSerialize = myHomeRegistry.parse(strToParse, args); + double t = System.nanoTime(); + + printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", " (after process)"); + print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + out.println("String \"" + strToParse + "\" was parsed into:\n\t" + toStringAndCls(objToSerialize)); + out.println("\n"); + + out.flush(); + return objToSerialize; + } + + if (objToSerialize != null) + { + if (args.length < 100) + { + myHomeRegistry.getRegistryIterationStackTrace().clear(); + args = Arrays.copyOf(args, 100); + args[99] = 0; + } + else if (args[99] instanceof Integer && (int) args[99] > 0) + { + myHomeRegistry = myHomeRegistry.clone(false); + } + + double t0 = System.nanoTime(); + strToParse = myHomeRegistry.toString(objToSerialize, args).toString(); + double t = System.nanoTime(); + + printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", " (after process)"); + print(out, "\n------- Registry iterations (" + myHomeRegistry.getRegistryIterationStackTrace().size() + " in total, total time " + (t-t0)/1000000 + "ms):", myHomeRegistry.getRegistryIterationStackTrace(), 0); + out.println("\n--------------------------------------------- " + action + " Results ---------------------------------------------"); + out.println("Object " + toStringAndCls(objToSerialize) + " was converted to string:\n" + (strToParse.contains("\n") ? strToParse : "\t" + strToParse)); + out.println("\n"); + + out.flush(); + return source.append(strToParse); + } + + printCacheInfo(out, myHomeRegistry.getParsingCache(), "parsing", ""); + printCacheInfo(out, myHomeRegistry.getConverterCache(), "converting", ""); + + out.println("\n--------------------------------------------- No Results ---------------------------------------------"); + if (myHomeRegistry.getParsingCache() != null && myHomeRegistry.getParsingCache().length > 0 || myHomeRegistry.getConverterCache() != null && myHomeRegistry.getConverterCache().length > 0) + out.println("If this is not the expected outcome you can try not using ParserRegistry caching or try to pre-cache some parsers!"); + out.println("\n"); + + out.flush(); + return VOID; + } + + /** + * Helper method for printing contents of {@link ParserRegistry#getParsingCache()}. + * + * @since 1.3.8 + */ + public static void printCacheInfo(PrintWriter out, DataParser[] cache, String cacheType, String additional) + { + if (cache == null) + out.println("\n------- Current " + cacheType + " cache" + additional + ": null (none)"); + else + print(out, "\n------- Current " + cacheType + " cache" + additional + ":", Arrays.asList(cache), 0); + } + + /** + * @param serializer | Serializer to debug! + * + * @return Serializer capable of debugging its serialization and deserialization! + * + * @since 1.3.5 + */ + public static T debug(T serializer) + { + return debug(serializer, new SerializationDebugger()); + } + + /** + * @param serializer | Serializer to debug! + * @param debugger | Specific debugger to use! + * + * @return Serializer capable of debugging its serialization and deserialization! + * + * @since 1.3.5 + */ + public static T debug(T serializer, SerializationDebugger debugger) + { + serializer.getParsers().add(0, debugger); + serializer.setParsers(new DebugParserRegistry(serializer.getParsers())); + return serializer; + } + + /** + * @param objToSerializeAndDebug | Object you want to serialize and see the debug of serialization! + * + * @return Object wrapped for debugger to debug! + * + * @since 1.3.5 + */ + public static DebugWrapper wrapForDebug(Object objToSerializeAndDebug) + { + return new DebugWrapper(objToSerializeAndDebug); + } + + /** + * @return obj + " (" + obj.getClass().getName() + ")" + * Note: Used internally by debugger! + * + * @since 1.3.5 + */ + public static String toStringAndCls(Object obj) + { + if (obj == null) + return "null"; + else + return obj + " (" + obj.getClass().getName() + ")"; + } + + /** + * This will print list into console in somewhat more readable form with tabs and introduction text! + * + * @since 1.3.5 + */ + public static void print(PrintWriter out, String text, List objs, int tabs) + { + out.println(text); + for (int i = 0, i2 = 0; i < objs.size(); i++) + { + Object o = objs.get(i); + String strTbs = multilpy('\t', tabs).toString(); + if (o instanceof List) + print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + else if (o instanceof Map) + print(out, strTbs + (i2++) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + else + out.println(multilpy('\t', tabs).toString() + (i2++) + ":\t" + String.valueOf(o)); + } + } + + /** + * This will print map into console in somewhat more readable form with tabs and introduction text! + * + * @since 1.3.5 + */ + public static void print(PrintWriter out, String text, Map map, int tabs) + { + out.println(text); + for (Entry entry : map.entrySet()) + { + Object o = entry.getValue(); + String strTbs = multilpy('\t', tabs).toString(); + if (o instanceof List) + print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (List) o, tabs+1); + else if (o instanceof Map) + print(out, strTbs + (entry.getKey()) + ":\t" + o.getClass().getName() + ":", (Map) o, tabs+1); + else + out.println(strTbs + entry.getKey() + ":\t" + String.valueOf(o)); + } + } + + /** + * Use this during converting/serializing! + * + * @author PETO + * + * @since 1.3.5 + * + * @see SerializationDebugger + */ + protected static class DebugWrapper + { + public final Object obj; + + /** + * @param yourObject | Your object to serialize in debug mode! + * + * @since 1.3.5 + */ + public DebugWrapper(Object yourObject) + { + obj = yourObject; + } + } } \ No newline at end of file diff --git a/SerialX-json/pom.xml b/SerialX-json/pom.xml index 0f75afb..12cbb32 100644 --- a/SerialX-json/pom.xml +++ b/SerialX-json/pom.xml @@ -1,25 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-json - 4.0.0-SNAPSHOT - - SerialX json - SerialX Json support - - - - org.ugp.serialx - serialx-juss - 4.0.0-SNAPSHOT - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-json + 4.0.0-SNAPSHOT + + SerialX json + SerialX Json support + + + + org.ugp.serialx + serialx-juss + 4.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 008520c..5942009 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -1,403 +1,403 @@ -package org.ugp.serialx.json; - -import static org.ugp.serialx.utils.Utils.isOneOf; -import static org.ugp.serialx.utils.Utils.multilpy; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.net.URL; -import java.net.URLConnection; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Map; -import java.util.Map.Entry; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.BooleanConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.NullConverter; -import org.ugp.serialx.converters.StringConverter; -import org.ugp.serialx.json.converters.JsonCharacterConverter; -import org.ugp.serialx.json.converters.JsonNumberConverter; -import org.ugp.serialx.json.converters.JsonObjectConverter; -import org.ugp.serialx.json.converters.JsonVariableConverter; -import org.ugp.serialx.juss.JussSerializer; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.Registry; - -/** - * This is implementation of {@link JussSerializer} for serializing in Json! - * It should generate and work with .json files! - *

- * Note: No Json specific syntax checks are made, only some small conventions and formating changes will occur to ensure Json syntax correctness but it will let you to use some Juss features freely so you can easily end up with some Json-juss hybrid! - * - * @author PETO - * - * @since 1.3.2 - */ -@SuppressWarnings("serial") -public class JsonSerializer extends JussSerializer -{ - /** - * This is representation of empty Json array. Use this instead of empty scope during serialization when you want to prevent it being serialized as empty Json object! - *

- * [] - * - * @since 1.3.5 - */ - public static final String EMPTY_ARRAY = StringConverter.DirectCode("[]"); - - /** - * This is representation of empty Json array. This is how empty scopes will be serialized by default! - *

- * [] - * - * @since 1.3.5 - * - * @see JsonSerializer#EMPTY_ARRAY - */ - public static final String EMPTY_OBJECT = StringConverter.DirectCode("{}"); - - public static final ParserRegistry JSON_PARSERS = new ParserRegistry(new JsonVariableConverter(), new StringConverter(), new JsonNumberConverter(), new BooleanConverter(false), new JsonCharacterConverter(false), new NullConverter(), new JsonObjectConverter()); - - /** - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JsonSerializer(Object... values) - { - this(null, values); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JsonSerializer(Map variablesMap, Object... values) - { - this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); - } - - /** - * @param sourceScope | Scope with initial content! - * - * @since 1.3.5 - */ - public JsonSerializer(GenericScope sourceScope) - { - this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JsonSerializer(Map variablesMap, Collection values) - { - this(JSON_PARSERS.clone(), variablesMap, values); - } - - /** - * @param parsers | Registry of parsers to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JsonSerializer(Registry parsers, Map variablesMap, Collection values) - { - this(parsers, SerializationProtocol.REGISTRY.clone(), variablesMap, values, null); - } - - /** - * @param parsers | Registry of parsers to use! - * @param protocols | Registry of protocols to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * @param parent | Parent of this scope. - * - * @since 1.3.2 - */ - public JsonSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) - { - super(parsers, protocols, variablesMap, values, parent); - } - - @Deprecated - @Override - public String Var(String name, T value, boolean isValue) - { - return Code((isValue ? "$\"" : "\"") + name + "\" = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? ", //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); - } - - @Override - public Object put(String variableName, Object variableValue) - { - if (isOneOf(variableName.charAt(0), '"', '\'') && isOneOf(variableName.charAt(variableName.length()-1), '"', '\'')) - variableName = variableName.substring(1, variableName.length()-1); - return super.put(variableName, variableValue); - } - - @Override - public JsonSerializer emptyClone(Scope parent) - { - JsonSerializer srl = emptyClone(new JsonSerializer(), parent); - return srl; - } - - @SuppressWarnings("unchecked") - @Override - public S loadFrom(Reader reader, Object... formatArgs) throws IOException - { - Scope sc = super.loadFrom(reader, formatArgs); - - if (formatArgs.length > 0 && formatArgs[0] instanceof Serializer) - return (S) sc; - Object jsonScope; - if (sc.valuesCount() == 1 && (jsonScope = sc.get(0)) instanceof Scope) - return (S) jsonScope; - return (S) sc; - } - - @Override - public A serializeTo(A source, Object... args) throws IOException - { - int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; - - if (tabs == 0 && !(valuesCount() == 1 && variablesCount() <= 0 && get(0) instanceof Scope)) - { - JussSerializer scope = emptyClone(null); - scope.add(this); - return scope.serializeTo(source, args); - } - return super.serializeTo(source, args); - } - - @Override - public ParserRegistry getParsers() - { - return parsers != null ? parsers : (parsers = JSON_PARSERS.clone()); - } - - /** - * This should append serializedVar into source based on arguments, add separator and return source! - * - * @since 1.3.2 - */ - @Override - protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException - { - if (format != 0) - source.append(multilpy('\t', tabs)); - if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) - return source; - return source.append(','); - } - - @Override - protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException - { - if (format != 0) - source.append(multilpy('\t', tabs)); - if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) - return source; - return source.append(','); - } - - @Override - public A serializeAsSubscope(A source, Object... args) throws IOException - { - return serializeAsSubscope(source, variablesCount() > 0 ? new char[] {'{', '}'} : new char[] {'[', ']'}, args); - } - - /** - * @param jussSerializer | JussSerializer to create {@link JsonSerializer} from! - * - * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! - * - * @since 1.3.2 - */ - public static JsonSerializer fromJussSerializer(JussSerializer jussSerializer) - { - if (jussSerializer instanceof JsonSerializer) - return (JsonSerializer) jussSerializer; - try - { - return jussSerializer.transformToScope().clone(JsonSerializer.class); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - } - - /** - * @param jsonSerializer | JsonSerializer to create {@link JussSerializer} from! - * - * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! - * - * @since 1.3.2 (since 1.3.8 moved from {@link JussSerializer} and renamed from "fromJsonSerializer" to "toJussSerializer") - */ - public static JussSerializer toJussSerializer(JsonSerializer jsonSerializer) - { - try - { - if (jsonSerializer.valuesCount() == 1 && jsonSerializer.variablesCount() == 0 && jsonSerializer.get(0) instanceof Scope) - { - GenericScope sc = (GenericScope) jsonSerializer.getScope(0); - if (sc instanceof Serializer) - return ((Serializer) sc).transformToScope().clone(JsonSerializer.class); - return sc.clone(JsonSerializer.class); - } - else - return jsonSerializer.transformToScope().clone(JsonSerializer.class); - } - catch (Exception e) - { - e.printStackTrace(); - return null; - } - } - - /** - * @param fromObj | Object to create serializer from! - * - * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

- * Table of specific Object --> JsonSerializer conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
- * - * @throws Exception When something went wrong during deserialization! - * - * @since 1.3.5 - */ - public static JsonSerializer from(Object fromObj) throws Exception - { - try - { - return from(fromObj, new String[0]); - } - catch (IntrospectionException e) - { - return new JsonSerializer(fromObj); - } - } - - /** - * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! - * - * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

- * Table of specific Object --> JsonSerializer conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
- * - * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! - * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! - * - * @since 1.3.5 - */ - public static JsonSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception - { - return (JsonSerializer) Serializer.from(new JsonSerializer(), fromObj, fieldNamesToUse); - } -} +package org.ugp.serialx.json; + +import static org.ugp.serialx.utils.Utils.isOneOf; +import static org.ugp.serialx.utils.Utils.multilpy; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.BooleanConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.NullConverter; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.json.converters.JsonCharacterConverter; +import org.ugp.serialx.json.converters.JsonNumberConverter; +import org.ugp.serialx.json.converters.JsonObjectConverter; +import org.ugp.serialx.json.converters.JsonVariableConverter; +import org.ugp.serialx.juss.JussSerializer; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.Registry; + +/** + * This is implementation of {@link JussSerializer} for serializing in
Json! + * It should generate and work with .json files! + *

+ * Note: No Json specific syntax checks are made, only some small conventions and formating changes will occur to ensure Json syntax correctness but it will let you to use some Juss features freely so you can easily end up with some Json-juss hybrid! + * + * @author PETO + * + * @since 1.3.2 + */ +@SuppressWarnings("serial") +public class JsonSerializer extends JussSerializer +{ + /** + * This is representation of empty Json array. Use this instead of empty scope during serialization when you want to prevent it being serialized as empty Json object! + *

+ * [] + * + * @since 1.3.5 + */ + public static final String EMPTY_ARRAY = StringConverter.DirectCode("[]"); + + /** + * This is representation of empty Json array. This is how empty scopes will be serialized by default! + *

+ * [] + * + * @since 1.3.5 + * + * @see JsonSerializer#EMPTY_ARRAY + */ + public static final String EMPTY_OBJECT = StringConverter.DirectCode("{}"); + + public static final ParserRegistry JSON_PARSERS = new ParserRegistry(new JsonVariableConverter(), new StringConverter(), new JsonNumberConverter(), new BooleanConverter(false), new JsonCharacterConverter(false), new NullConverter(), new JsonObjectConverter()); + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public JsonSerializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Map variablesMap, Collection values) + { + this(JSON_PARSERS.clone(), variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JsonSerializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, SerializationProtocol.REGISTRY.clone(), variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public JsonSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(parsers, protocols, variablesMap, values, parent); + } + + @Deprecated + @Override + public String Var(String name, T value, boolean isValue) + { + return Code((isValue ? "$\"" : "\"") + name + "\" = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? ", //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + } + + @Override + public Object put(String variableName, Object variableValue) + { + if (isOneOf(variableName.charAt(0), '"', '\'') && isOneOf(variableName.charAt(variableName.length()-1), '"', '\'')) + variableName = variableName.substring(1, variableName.length()-1); + return super.put(variableName, variableValue); + } + + @Override + public JsonSerializer emptyClone(Scope parent) + { + JsonSerializer srl = emptyClone(new JsonSerializer(), parent); + return srl; + } + + @SuppressWarnings("unchecked") + @Override + public S loadFrom(Reader reader, Object... formatArgs) throws IOException + { + Scope sc = super.loadFrom(reader, formatArgs); + + if (formatArgs.length > 0 && formatArgs[0] instanceof Serializer) + return (S) sc; + Object jsonScope; + if (sc.valuesCount() == 1 && (jsonScope = sc.get(0)) instanceof Scope) + return (S) jsonScope; + return (S) sc; + } + + @Override + public A serializeTo(A source, Object... args) throws IOException + { + int tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; + + if (tabs == 0 && !(valuesCount() == 1 && variablesCount() <= 0 && get(0) instanceof Scope)) + { + JussSerializer scope = emptyClone(null); + scope.add(this); + return scope.serializeTo(source, args); + } + return super.serializeTo(source, args); + } + + @Override + public ParserRegistry getParsers() + { + return parsers != null ? parsers : (parsers = JSON_PARSERS.clone()); + } + + /** + * This should append serializedVar into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + @Override + protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException + { + if (format != 0) + source.append(multilpy('\t', tabs)); + if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) + return source; + return source.append(','); + } + + @Override + protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException + { + if (format != 0) + source.append(multilpy('\t', tabs)); + if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) + return source; + return source.append(','); + } + + @Override + public A serializeAsSubscope(A source, Object... args) throws IOException + { + return serializeAsSubscope(source, variablesCount() > 0 ? new char[] {'{', '}'} : new char[] {'[', ']'}, args); + } + + /** + * @param jussSerializer | JussSerializer to create {@link JsonSerializer} from! + * + * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! + * + * @since 1.3.2 + */ + public static JsonSerializer fromJussSerializer(JussSerializer jussSerializer) + { + if (jussSerializer instanceof JsonSerializer) + return (JsonSerializer) jussSerializer; + try + { + return jussSerializer.transformToScope().clone(JsonSerializer.class); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + /** + * @param jsonSerializer | JsonSerializer to create {@link JussSerializer} from! + * + * @return JussSerializer created from JsonSerializer, all values and variables will remain intact! + * + * @since 1.3.2 (since 1.3.8 moved from {@link JussSerializer} and renamed from "fromJsonSerializer" to "toJussSerializer") + */ + public static JussSerializer toJussSerializer(JsonSerializer jsonSerializer) + { + try + { + if (jsonSerializer.valuesCount() == 1 && jsonSerializer.variablesCount() == 0 && jsonSerializer.get(0) instanceof Scope) + { + GenericScope sc = (GenericScope) jsonSerializer.getScope(0); + if (sc instanceof Serializer) + return ((Serializer) sc).transformToScope().clone(JsonSerializer.class); + return sc.clone(JsonSerializer.class); + } + else + return jsonSerializer.transformToScope().clone(JsonSerializer.class); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + } + + /** + * @param fromObj | Object to create serializer from! + * + * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JsonSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception When something went wrong during deserialization! + * + * @since 1.3.5 + */ + public static JsonSerializer from(Object fromObj) throws Exception + { + try + { + return from(fromObj, new String[0]); + } + catch (IntrospectionException e) + { + return new JsonSerializer(fromObj); + } + } + + /** + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link JsonSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JsonSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + public static JsonSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return (JsonSerializer) Serializer.from(new JsonSerializer(), fromObj, fieldNamesToUse); + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java index dc23217..2ad1a5a 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonCharacterConverter.java @@ -1,55 +1,55 @@ -package org.ugp.serialx.json.converters; - -import java.io.IOException; - -import org.ugp.serialx.converters.CharacterConverter; - -/** - * {@link CharacterConverter} modified to match JSON more closely. It will serialize char as {@link String} since JSON does not know char... - * - * @author PETO - * - * @since 1.3.8 - */ -public class JsonCharacterConverter extends CharacterConverter -{ - protected boolean formatAsString; - - /** - * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). - * - * @since 1.3.8 - */ - public JsonCharacterConverter(boolean formatAsString) - { - setFormatAsString(formatAsString); - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Character) - return source.append(isFormatAsString() ? "\""+obj+"\"" : String.valueOf((int) (char) obj)); - return CONTINUE; - } - - /** - * @return True if character is going to be serialized in a letter form. If false, it will be serialized as ASCII value (int). - * - * @since 1.3.8 - */ - public boolean isFormatAsString() - { - return formatAsString; - } - - /** - * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). - * - * @since 1.3.8 - */ - public void setFormatAsString(boolean formatAsString) - { - this.formatAsString = formatAsString; - } -} +package org.ugp.serialx.json.converters; + +import java.io.IOException; + +import org.ugp.serialx.converters.CharacterConverter; + +/** + * {@link CharacterConverter} modified to match JSON more closely. It will serialize char as {@link String} since JSON does not know char... + * + * @author PETO + * + * @since 1.3.8 + */ +public class JsonCharacterConverter extends CharacterConverter +{ + protected boolean formatAsString; + + /** + * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). + * + * @since 1.3.8 + */ + public JsonCharacterConverter(boolean formatAsString) + { + setFormatAsString(formatAsString); + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Character) + return source.append(isFormatAsString() ? "\""+obj+"\"" : String.valueOf((int) (char) obj)); + return CONTINUE; + } + + /** + * @return True if character is going to be serialized in a letter form. If false, it will be serialized as ASCII value (int). + * + * @since 1.3.8 + */ + public boolean isFormatAsString() + { + return formatAsString; + } + + /** + * @param formatAsString | If true, character will be serialized in a letter form. Otherwise it will be serialized as ASCII value (int). + * + * @since 1.3.8 + */ + public void setFormatAsString(boolean formatAsString) + { + this.formatAsString = formatAsString; + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java index 666667f..45981c8 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonNumberConverter.java @@ -1,23 +1,23 @@ -package org.ugp.serialx.json.converters; - -import java.io.IOException; - -import org.ugp.serialx.converters.NumberConverter; - -/** - * {@link NumberConverter} modified to match JSON more closely. It will not use Juss number suffixes since JSON does not support them... - * - * @author PETO - * - * @since 1.3.8 - */ -public class JsonNumberConverter extends NumberConverter -{ - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Number) - return source.append(format((Number) obj)); - return CONTINUE; - } -} +package org.ugp.serialx.json.converters; + +import java.io.IOException; + +import org.ugp.serialx.converters.NumberConverter; + +/** + * {@link NumberConverter} modified to match JSON more closely. It will not use Juss number suffixes since JSON does not support them... + * + * @author PETO + * + * @since 1.3.8 + */ +public class JsonNumberConverter extends NumberConverter +{ + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Number) + return source.append(format((Number) obj)); + return CONTINUE; + } +} diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index 62a55f5..f2b657b 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -1,61 +1,61 @@ -package org.ugp.serialx.json.converters; - -import java.io.IOException; -import java.util.Map; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.json.JsonSerializer; -import org.ugp.serialx.juss.converters.ObjectConverter; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.Utils; - -/** - * Used internally by {@link JsonSerializer} to ensure proper and valid Json format for scopes and protocols. - * - * @author PETO - * - * @since 1.3.5 (separated from JsonSerializer since 1.3.8) - */ -public class JsonObjectConverter extends ObjectConverter -{ - @SuppressWarnings("unchecked") - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj == null) - return CONTINUE; - - if (obj.getClass().isArray()) - return super.toString(source, myHomeRegistry, new Scope(Utils.fromAmbiguousArray(obj)), args); - - if (obj instanceof Map) - { - Map map = (Map) obj; - if (map.isEmpty()) - return source.append("{}"); - if (map.keySet().iterator().next() instanceof CharSequence) - return super.toString(source, myHomeRegistry, new Scope((Map) map), args); - } - - SerializationProtocol prot = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE, args); - if (prot != null && !(obj instanceof Scope)) - try - { - Object[] objArgs = prot.serialize(obj); - if (objArgs.length == 1 && objArgs[0] instanceof Scope) - return super.toString(source, myHomeRegistry, objArgs[0], args); - return super.toString(source, myHomeRegistry, new Scope(objArgs), args); - } - catch (Exception e) - {} - - return super.toString(source, myHomeRegistry, obj, prot, args); - } - - @Override - public Serializer getPreferredSerializer() - { - return new JsonSerializer(); - } +package org.ugp.serialx.json.converters; + +import java.io.IOException; +import java.util.Map; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.json.JsonSerializer; +import org.ugp.serialx.juss.converters.ObjectConverter; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.Utils; + +/** + * Used internally by {@link JsonSerializer} to ensure proper and valid Json format for scopes and protocols. + * + * @author PETO + * + * @since 1.3.5 (separated from JsonSerializer since 1.3.8) + */ +public class JsonObjectConverter extends ObjectConverter +{ + @SuppressWarnings("unchecked") + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj == null) + return CONTINUE; + + if (obj.getClass().isArray()) + return super.toString(source, myHomeRegistry, new Scope(Utils.fromAmbiguousArray(obj)), args); + + if (obj instanceof Map) + { + Map map = (Map) obj; + if (map.isEmpty()) + return source.append("{}"); + if (map.keySet().iterator().next() instanceof CharSequence) + return super.toString(source, myHomeRegistry, new Scope((Map) map), args); + } + + SerializationProtocol prot = (SerializationProtocol) getProtocolFor(obj, SerializationProtocol.MODE_SERIALIZE, args); + if (prot != null && !(obj instanceof Scope)) + try + { + Object[] objArgs = prot.serialize(obj); + if (objArgs.length == 1 && objArgs[0] instanceof Scope) + return super.toString(source, myHomeRegistry, objArgs[0], args); + return super.toString(source, myHomeRegistry, new Scope(objArgs), args); + } + catch (Exception e) + {} + + return super.toString(source, myHomeRegistry, obj, prot, args); + } + + @Override + public Serializer getPreferredSerializer() + { + return new JsonSerializer(); + } } \ No newline at end of file diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java index a41ba05..ea5c010 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonVariableConverter.java @@ -1,31 +1,31 @@ -package org.ugp.serialx.json.converters; - -import java.io.IOException; -import java.util.Map.Entry; - -import org.ugp.serialx.juss.converters.VariableConverter; - -/** - * Json specific {@link VariableConverter}. Wraps keys in "" and uses : instead of = - * - * @since 1.3.9 - */ -public class JsonVariableConverter extends VariableConverter -{ - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Entry) - { - Entry var = (Entry) obj; - - source.append('"').append(String.valueOf(var.getKey())); - if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) - source.append("\" : "); - else - source.append("\":"); - return myHomeRegistry.toString(source, var.getValue(), args); - } - return CONTINUE; - } -} +package org.ugp.serialx.json.converters; + +import java.io.IOException; +import java.util.Map.Entry; + +import org.ugp.serialx.juss.converters.VariableConverter; + +/** + * Json specific {@link VariableConverter}. Wraps keys in "" and uses : instead of = + * + * @since 1.3.9 + */ +public class JsonVariableConverter extends VariableConverter +{ + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Entry) + { + Entry var = (Entry) obj; + + source.append('"').append(String.valueOf(var.getKey())); + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + source.append("\" : "); + else + source.append("\":"); + return myHomeRegistry.toString(source, var.getValue(), args); + } + return CONTINUE; + } +} diff --git a/SerialX-juss/pom.xml b/SerialX-juss/pom.xml index 74a5921..07fee21 100644 --- a/SerialX-juss/pom.xml +++ b/SerialX-juss/pom.xml @@ -1,25 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-juss - 4.0.0-SNAPSHOT - - SerialX juss - SerialX support for Java Universal Serial Script data format, custom default format of SerialX! - - - - org.ugp.serialx - serialx-core - 4.0.0-SNAPSHOT - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-juss + 4.0.0-SNAPSHOT + + SerialX juss + SerialX support for Java Universal Serial Script data format, custom default format of SerialX! + + + + org.ugp.serialx + serialx-core + 4.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index ecb6614..a353220 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,1028 +1,1028 @@ -package org.ugp.serialx.juss; - -import static org.ugp.serialx.converters.DataParser.VOID; -import static org.ugp.serialx.utils.Utils.Clone; -import static org.ugp.serialx.utils.Utils.ENDL; -import static org.ugp.serialx.utils.Utils.InvokeStaticFunc; -import static org.ugp.serialx.utils.Utils.isOneOf; -import static org.ugp.serialx.utils.Utils.multilpy; - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.io.BufferedReader; -import java.io.File; -import java.io.Flushable; -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; -import java.net.URL; -import java.net.URLConnection; -import java.text.SimpleDateFormat; -import java.util.AbstractMap; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.BooleanConverter; -import org.ugp.serialx.converters.CharacterConverter; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.NullConverter; -import org.ugp.serialx.converters.NumberConverter; -import org.ugp.serialx.converters.SerializableBase64Converter; -import org.ugp.serialx.converters.StringConverter; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.juss.converters.ArrayConverter; -import org.ugp.serialx.juss.converters.ImportConverter; -import org.ugp.serialx.juss.converters.ObjectConverter; -import org.ugp.serialx.juss.converters.OperationGroups; -import org.ugp.serialx.juss.converters.VariableConverter; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.Registry; -import org.ugp.serialx.utils.Utils; - -/** - * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! - * It should generate and work with .juss or .srlx files! - * - * @author PETO - * - * @since 1.3.2 - */ -@SuppressWarnings("serial") -public class JussSerializer extends Serializer implements ImportsProvider -{ - /** - * {@link ParserRegistry} with all parsers required to parse JUSS! - * - * @since 1.3.2 - */ - public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new ImportConverter(), new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); - - /** - * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. - *
- * Since 1.3.8 this requires "org.ugp.serialx.converters.Operators" from SerialX "operators" modules to be present on the classpath! - * - * @since 1.3.2 - */ - public static final ParserRegistry JUSS_PARSERS_AND_OPERATORS; - - static - { - JUSS_PARSERS.add(0, new ImportConverter()); - JUSS_PARSERS_AND_OPERATORS = JUSS_PARSERS.clone(); - - try - { - InvokeStaticFunc(Class.forName("org.ugp.serialx.converters.Operators"), "install", JUSS_PARSERS_AND_OPERATORS); - } - catch (Exception e) - {} - } - - protected Imports imports; - - /** - * @deprecated (1.3.9) SET 0b10 BIT OF {@link Serializer#getFormat()} TO 1 INSTEAD IF YOU WANT TO SET THIS ON TRUE. OR SIMPLY USE {@link JussSerializer#setGenerateComments(boolean)} - * - * Set this on true and program will generate comments and report!
- * Note: Keep this on false to achieve the best performance! - * - * @since 1.0.5 - */ - @Deprecated - protected boolean generateComments = false; - - /** - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JussSerializer(Object... values) - { - this(null, values); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JussSerializer(Map variablesMap, Object... values) - { - this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); - } - - /** - * @param sourceScope | Scope with initial content! - * - * @since 1.3.5 - */ - public JussSerializer(GenericScope sourceScope) - { - this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); - } - - /** - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JussSerializer(Map variablesMap, Collection values) - { - this(null, variablesMap, values); - } - - /** - * @param parsers | Registry of parsers to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * - * @since 1.3.2 - */ - public JussSerializer(Registry parsers, Map variablesMap, Collection values) - { - this(parsers, null, variablesMap, values, null); - } - - /** - * @param parsers | Registry of parsers to use! - * @param protocols | Registry of protocols to use! - * @param variablesMap | Initial variables to be added in to this scope! - * @param values | Initial independent values to be added in to this scope! - * @param parent | Parent of this scope. - * - * @since 1.3.2 - */ - public JussSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) - { - super(parsers, protocols, variablesMap, values, parent); - } - - @Override - public JussSerializer emptyClone(Scope parent) - { - JussSerializer srl = emptyClone(new JussSerializer(), parent); - return srl; - } - - @Override - public ParserRegistry getParsers() - { - return parsers != null ? parsers : (parsers = JUSS_PARSERS.clone()); - } - - @Override - public Imports getImports() - { - if (imports == null) - imports = ImportsProvider.IMPORTS.clone(); - return imports; - } - - /** - * @param absoluteClone | If true this scope will be cloned using {@link Utils#Clone}, if false {@link Scope#clone()}! - * - * @return Clone of this scope! - * - * @since 1.3.2 - */ - public Scope clone(boolean absoluteClone) - { - if (absoluteClone) - return Clone(this, getParsers(), new Object[] {this, -9999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); - return super.clone(); - } - - /** - * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! - * - * @param name | Name of variable. - * @param value | Value of variable. - * - * @return Variable in JUSS form to serialize as [name] = [value]. - * - * @since 1.1.5 - */ - @Deprecated - @Override - public String Var(String name, T value) - { - return Var(name, value, false); - } - - /** - * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! - * - * @param name | Name of variable. - * @param value | Value of variable. - * @param isValue | True if variables value supposed to by visible also during value loading. - * - * @return Variable in JUSS form to serialize as [name] = [value]. - * - * @since 1.1.5 - */ - @Deprecated - public String Var(String name, T value, boolean isValue) - { - return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); - } - - /** - * @param cls | Class to invoke static member on! - * @param staticMethodName | Name of static member! - * @param args | Arguments of method (use this only if you are invoking method no field)! - * - * @return Static member invocation in JUSS form to serialize as [class]::[method | field] [args]... - *

Note: This will not invoke member from class directly, it will be invoked during unserialization, also no checks are performed here so this will not notify you if member or class does not exist!
- * Also this will work only in combination {@link ObjectConverter}! - * - * @since 1.2.2 - */ - public String StaticMember(Class cls, String staticMethodName, Object... args) - { - StringBuilder sb = new StringBuilder(cls.getName()).append("::").append(staticMethodName); - for (int i = 0, len = args.length; i < len; i++) - { - sb.append(' '); - - try - { - getParsers().toString(sb, args[i], this, 0, 0, getProtocols(), getFormat()); - } - catch (IOException e) - { - throw new RuntimeException(e); // No... - } - } - return Code(sb); - } - - /** - * @param source | Source {@link Appendable} to serialize variables and objects into! - * @param args | Additional arguments to use, in case of {@link JussSerializer} this should be array of length 6 with 0. argument being this pointer to this serializer, - * argument 1. and 2. being integers signifying number of tabs and index of parsing iteration (used primarily by {@link ObjectConverter}), argument 3. containing {@link ProtocolRegistry} of this {@link Serializer}, - * argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null), - * and argument 5. being byte bit array containing the formating flags ({@link Serializer#getFormat()}) containing the information about if the code comments are supposed to be generated and/or indentation and newline characters inclusion! - * - * @return Source {@link Appendable} with variables and objects serialized in specific format. - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - @Override - public A serializeTo(A source, Object... args) throws IOException - { - Map variables = variables(); - List objs = values(); - int valuesLen = objs.size(), varLen = variables.size(), i = 0, tabs = 0; - boolean generateComments = isGenerateComments(); - - if (args.length < 6) - args = Arrays.copyOf(args, 6); - args[0] = this; - if (args[1] == null) - args[1] = tabs; //tabs - else if (args[1] instanceof Integer) - tabs = (int) args[1]; - if (args[2] == null) - args[2] = 0; //index - if (args[3] == null) - args[3] = getProtocols(); - if (args[5] == null) - args[5] = getFormat(); - - source = source == null ? (A) new StringBuilder() : source; - if (generateComments && varLen + valuesLen > 0) //Gen scope comment - { - if (tabs <= 0) - source.append("//Date created: ").append(new SimpleDateFormat("MM-dd-yyyy 'at' HH:mm:ss z \n\n").format(new Date())); - source.append(multilpy('\t', tabs)).append("//Scope serialization summary:\n"); - if (varLen > 0) - source.append(multilpy('\t', tabs)).append("//").append(varLen+"").append(" variables!\n"); - - if (valuesLen > 0) - source.append(multilpy('\t', tabs)).append("//").append(valuesLen+"").append(" values!\n"); - if (tabs > -1) - source.append('\n'); - } - - ParserRegistry reg = getParsers(); - - if (varLen > 0) - { - if (generateComments) - { - for (Entry var : variables.entrySet()) //Vars - { - appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); - if (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty()) - GenerateComment(source, reg, var); - - if (++i < varLen || valuesLen > 0) - source.append('\n'); - } - } - else if (format != 0) - { - for (Entry var : variables.entrySet()) //Vars - { - appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); - - if (++i < varLen || valuesLen > 0) - source.append('\n'); - } - } - else // No formating - { - for (Entry var : variables.entrySet()) //Vars - { - appandVar(source, reg, var, tabs, i++ >= varLen-1 && valuesLen <= 0, args); - } - } - } - - if (generateComments) - { - for (i = 0; i < valuesLen; i++) //Values - { - if (i != 0) - source.append('\n'); - - Object obj; - appandVal(source, reg, obj = objs.get(i), tabs, i == valuesLen-1, args); - if (!(obj instanceof Scope) || ((Scope) obj).isEmpty()) - GenerateComment(source, reg, obj); - } - } - else if (format != 0) - { - for (i = 0; i < valuesLen; i++) //Values - { - if (i != 0) - source.append('\n'); - - appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); - } - } - else // No formating - { - for (i = 0; i < valuesLen; i++) //Values - { - appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); - } - } - - if (source instanceof Flushable) - ((Flushable) source).flush(); - if (tabs == 0) - getImports().removeImportsOf(this); - return source; - } - - /** - * his should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) varToSerialize into source based on arguments, add separator and return source! - * - * @since 1.3.2 - */ - protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException - { - if (format != 0) - source.append(multilpy('\t', tabs)); - if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) - return source; - return source.append(';'); - } - - /** - * This should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) objToSerialize into source based on arguments, add separator and return source! - * - * @since 1.3.2 - */ - protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException - { - if (format != 0) - source.append(multilpy('\t', tabs)); - if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) - return source; - return source.append(';'); - } - - /** - * @return Generated description for obj, appended in source! - * - * @since 1.3.2 - */ - public Appendable GenerateComment(Appendable source, ParserRegistry registry, Object obj) throws IOException - { - try - { - CharSequence comment = registry.getConverterFor(obj).getDescription(registry, obj); - if (comment.length() > 0) - return source.append(" //").append(comment); - } - catch (Exception e) - { - return source.append(" //").append(DataConverter.getDefaultDescriptionFor(obj)); - } - return source; - } - - /** - * @param reader | Reader to read from! - * @param args | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this serializer, - * 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, - * and additional argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null). - * - * @return This scope after loading data from reader (you most likely want to return "this")! - * - * @throws IOException When reading the reader fails... - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - @Override - public S loadFrom(Reader reader, Object... args) throws IOException - { -// boolean formatRequired = true; - - if (args.length < 4) - args = Arrays.copyOf(args, 4); -// if (args[0] instanceof Boolean) -// formatRequired = (boolean) args[0]; - args[0] = this; - if (args[3] == null) - args[3] = getProtocols(); - -// StringBuilder str = readAndFormat(reader, formatRequired); -// List objs = splitAndParse(str, args); -// addAll(objs); - - readAndParse(values(), reader, 512, args); - - if (parent == null) - getImports().removeImportsOf(this); - return (S) this; - } - - /** - * This acts basically as reader + lexer for Juss and Json input... - * - * @param result | Resulting collection of objects to fill up with parsed objects from reader. - * @param reader | The reader to {@link Reader#read(char[], int, int)}. - * @param charBuffLen | Length of internal char buffer (number of chars that are processed at once). Recommended length is 512, in case of increase should be the power of 2. - * @param parserArgs | Additional arguments to use. Take a look at {@link Serializer#loadFrom(File, Object...)}. - * - * @throws IOException If {@link Reader} instance throws it during reading... - * - * @since 1.3.9 - */ - public void readAndParse(Collection result, Reader reader, final int charBuffLen, Object... parserArgs) throws IOException - { - ParserRegistry reg = getParsers(); - - StringBuilder sb = new StringBuilder(); - int len; - - char chars[] = new char[charBuffLen], oldCh = 0; - readerLoop: for (int charsRead, /*state = 0,*/ brackets; (charsRead = reader.read(chars, 0, charBuffLen)) != -1; ) - { - charsLoop: for (int i = 0; i < charsRead; i++) - { - char ch = chars[i]; - - if (oldCh == '/') // Skip the comments... - { - if (ch == '/' || ch == '*') // // | /* - { - sb.setLength(len = (sb.length() - 1)); // Pop / and restore old char, important! - oldCh = len == 0 ? 0 : sb.charAt(len - 1); - for (;;) // Skip all till end of comm - { - if (++i >= charsRead) // Check and read on if necessary... - if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) - i = 0; - else break readerLoop; - - if (ch == '/' ? - isOneOf(chars[i], ENDL) : - chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/' // */ - ) { - continue charsLoop; - } - } - } - } - - if (ch == '\"' || ch == '\'') - { - sb.append(ch); - for (oldCh = ch; ; ) // Append all chars until end of str/char - { - if (++i >= charsRead) // Check and read on if necessary... - if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) - i = 0; - else break readerLoop; - - sb.append(ch = chars[i]); - if (ch == oldCh) - continue charsLoop; // break; - } - } - else if ((ch | ' ') == '{') - { - sb.append(ch); - brackets = 1; - do - { - if (++i >= charsRead) // Check and read on if necessary... - if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) - i = 0; - else break readerLoop; - - sb.append(ch = chars[i]); - if ((ch |= ' ') == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '\"' || ch == '\'') - { - for (oldCh = ch; ; ) // Append all chars until end of str/char - { - if (++i >= charsRead) // Check and read on if necessary... - if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) - i = 0; - else break readerLoop; - - sb.append(ch = chars[i]); - if (ch == oldCh) - break; - } - } - } - while (brackets != 0); - } - else if (ch == ';' || ch == ',' || (oldCh == '}' && isOneOf(ch, ENDL))) - { - if ((len = sb.length()) != 0) - { - if (oldCh == ' ') // Trim - sb.setLength(--len); - - if (len != 0) - { -// System.err.println("|" + sb.toString() + "| " + (oldCh == ' ') + "\n"); - Object obj = parseObject(reg, sb.toString(), parserArgs); - if (obj != VOID) - result.add(obj); - sb.setLength(0); - } - } - - oldCh = 0; - continue; - } - else if (ch <= ' ') // Handle blanks, skip unnecessary - { - if (oldCh > ' ') // First blank (in possible row) - sb.append(oldCh /*= state*/ = ' '); - continue; - } - else - sb.append(ch); - - oldCh = ch; - } - } - - if ((len = sb.length()) == 0) - return; - - if (oldCh == ' ') // Trim - sb.setLength(--len); - - if (len != 0) - { -// System.err.println("|" + sb.toString() + "| " + (oldCh) + "\n"); - Object obj = parseObject(reg, sb.toString(), parserArgs); - if (obj != VOID) - result.add(obj); - } - } - - /** - * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! - * - * @return Formated content of reader ready to parse! Should not modify this object in any way! - * - * @since 1.3.2 - */ - @Deprecated - public StringBuilder readAndFormat(Reader reader, boolean format) - { - int quote = 0, multLineCom = -1; - //int brackets = 0, lastIndex = 0, delChars = 0; - StringBuilder sb = new StringBuilder(); - - try - { - BufferedReader lineReader = new BufferedReader(reader); - //String blanks = new String(new char[] {32, 9, 10, 12, 13}); - for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) - { - if (format) - { - int lastNotBlank = -1; - for (int i = 0, com = -1, len = line.length(); i < len; i++) - { - char ch = line.charAt(i); - - boolean notString = quote % 2 == 0; - if (multLineCom > -1 || com > -1) //Is comment - { - if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') - com = multLineCom = -1; - } - else if (notString && ch == '/' && i < len-1) - { - if (line.charAt(i+1) == '*') - i += multLineCom = 1; - else if (line.charAt(i+1) == '/') - com++; - else - sb.append('/'); - } - else if (notString && ch >= 9 && ch <= 13) - sb.append(' '); - else - { - /*if (notString) - { - if (ch | ' ') == '{' || ch == '[') - brackets++; - else if (ch == '}' || ch == ']') - { - if (brackets > 0) - brackets--; - else - throw new IllegalArgumentException("Missing opening bracket in: " + line); - } - else if (brackets == 0 && isOneOf(ch, ';', ',')) - { - System.out.println(sb); - sb = new StringBuilder(); - continue; - } - }*/ - if (ch > 32) - { - lastNotBlank = ch; - if (ch == '"') - quote++; - } - sb.append(ch); - } - } - sb.append((lastNotBlank | ' ') == '}' ? ';' : ' '); - } - else - sb.append(line).append('\n'); - } - lineReader.close(); - } - catch (IOException e) - { - e.printStackTrace(); - } - - return sb; - } - - /** - * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! - * - * @return List of objects parsed from given formatted string! - * - * @since 1.3.2 - */ - @Deprecated - public List splitAndParse(StringBuilder formattedStr, Object... parserArgs) - { - List result = new ArrayList<>(); - - ParserRegistry reg = getParsers(); - - //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; - int lastIndex = 0, len = formattedStr.length(); - //boolean isBracketSplit = false; - for (int i = 0; i < len; i++) - { - int ch = formattedStr.charAt(i); - if (ch == '"') - { - do if (++i >= len) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); - while (formattedStr.charAt(i) != '"'); - } - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + formattedStr); - if ((ch = (formattedStr.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && formattedStr.charAt(i) != '"'); - } - } - else if ((ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) - { - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); - if (!str.isEmpty()) - { -// System.out.println("|" + str + "|\n"); - Object obj = parseObject(reg, str, parserArgs); - if (obj != VOID) - result.add(obj); - } - //add = 1; - } - } - - String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); - if (!str.isEmpty()) - { -// System.out.println("|" + str + "|\n"); - Object obj = parseObject(reg, str, parserArgs); - if (obj != VOID) - result.add(obj); - } - return result; - } - -// /** -// * @return Object converted to string! -// *

-// * Note: Used by {@link JussSerializer#SerializeTo(Appendable, Object...)}! -// * -// * @see DataConverter#objToString(Registry, String, Object...) -// * -// * @since 1.3.5 -// */ -// public CharSequence objectToStr(Registry registry, Object obj, Object... parserArgs) -// { -// return -// } - - /** - * @return Object parsed from str! - *

- * Note: Used by {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)}! - * - * @see ParserRegistry#parse(ParserRegistry, String, Object...) - * - * @since 1.3.2 - */ - protected Object parseObject(ParserRegistry registry, String str, Object... parserArgs) - { - return registry.parse(str, parserArgs); - } - - /** - * @param variableKey | Variable to clone! - * - * @return Clone of value stored by variable with inserted name or null if there is no such a one! - *

- * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! - * - * @since 1.3.2 - */ - public T cloneOf(String variableKey) - { - return cloneOf(variableKey, null); - } - - /** - * @param variableKey | Variable to clone! - * @param defaultValue | Default value to return. - * - * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! - *

- * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! - * - * @since 1.3.2 - */ - public T cloneOf(String variableKey, T defaultValue) - { - T obj = get(variableKey, defaultValue); - if (obj == defaultValue) - return defaultValue; - return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); - } - - /** - * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! - * {@link IndexOutOfBoundsException} will be thrown if index is too big! - * - * @return Clone of independent value with valueIndex! - *

- * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! - * - * @since 1.3.2 - */ - public T cloneOf(int valueIndex) - { - T obj = get(valueIndex); - return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); - } - - /** - * @return True if comment supposed to be generated! - * - * @since 1.3.2 - */ - public boolean isGenerateComments() - { - return (format & 0b10) != 0; - } - - /** - * @param generateComments | If true, comments will be generated during serialization! - * - * @since 1.3.2 - */ - public void setGenerateComments(boolean generateComments) - { - if (generateComments) - format |= 0b10; - else - format &= 0xff ^ 0b10; - } - -// /** -// * @return True if used parsers and converters are cached during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! -// * -// * @since 1.3.5 -// * -// * @see ParserRegistry#resetCache() -// */ -// public boolean isSerializationAutoCaching() -// { -// return serializationAutoCaching; -// } -// -// /** -// * @param serializationAutoCaching | Set this on true to allow caching of used parsers and converters during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! -// * -// * @since 1.3.5 -// * -// * @see ParserRegistry#resetCache() -// * @see ParserRegistry#destroyCache() -// */ -// public void setSerializationAutoCaching(boolean serializationAutoCaching) -// { -// if (!(this.serializationAutoCaching = serializationAutoCaching)) -// getParsers().destroyCache(); -// } - - /** - * @param fromObj | Object to create serializer from! - * - * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

- * Table of specific Object --> JussSerializer conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
- * - * @throws Exception If something went wrong during deserialization! - * - * @since 1.3.5 - */ - public static JussSerializer from(Object fromObj) throws Exception - { - try - { - return from(fromObj, new String[0]); - } - catch (IntrospectionException e) - { - return new JussSerializer(fromObj); - } - } - - /** - * @param fromObj | Object to create serializer from! - * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! - * - * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

- * Table of specific Object --> JussSerializer conversions: - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
- * - * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! - * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! - * - * @since 1.3.5 - */ - public static JussSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception - { - return (JussSerializer) Serializer.from(new JussSerializer(), fromObj, fieldNamesToUse); - } -} +package org.ugp.serialx.juss; + +import static org.ugp.serialx.converters.DataParser.VOID; +import static org.ugp.serialx.utils.Utils.Clone; +import static org.ugp.serialx.utils.Utils.ENDL; +import static org.ugp.serialx.utils.Utils.InvokeStaticFunc; +import static org.ugp.serialx.utils.Utils.isOneOf; +import static org.ugp.serialx.utils.Utils.multilpy; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.io.BufferedReader; +import java.io.File; +import java.io.Flushable; +import java.io.IOException; +import java.io.InputStream; +import java.io.Reader; +import java.net.URL; +import java.net.URLConnection; +import java.text.SimpleDateFormat; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.BooleanConverter; +import org.ugp.serialx.converters.CharacterConverter; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.NullConverter; +import org.ugp.serialx.converters.NumberConverter; +import org.ugp.serialx.converters.SerializableBase64Converter; +import org.ugp.serialx.converters.StringConverter; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.juss.converters.ArrayConverter; +import org.ugp.serialx.juss.converters.ImportConverter; +import org.ugp.serialx.juss.converters.ObjectConverter; +import org.ugp.serialx.juss.converters.OperationGroups; +import org.ugp.serialx.juss.converters.VariableConverter; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.Registry; +import org.ugp.serialx.utils.Utils; + +/** + * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! + * It should generate and work with .juss or .srlx files! + * + * @author PETO + * + * @since 1.3.2 + */ +@SuppressWarnings("serial") +public class JussSerializer extends Serializer implements ImportsProvider +{ + /** + * {@link ParserRegistry} with all parsers required to parse JUSS! + * + * @since 1.3.2 + */ + public static final ParserRegistry JUSS_PARSERS = new ParserRegistry(new ImportConverter(), new OperationGroups(), new VariableConverter(), new StringConverter(), new ObjectConverter(), new ArrayConverter(), new NumberConverter(), new BooleanConverter(), new CharacterConverter(), new NullConverter(), new SerializableBase64Converter()); + + /** + * {@link ParserRegistry} with all parsers required to parse JUSS with additional operators. + *
+ * Since 1.3.8 this requires "org.ugp.serialx.converters.Operators" from SerialX "operators" modules to be present on the classpath! + * + * @since 1.3.2 + */ + public static final ParserRegistry JUSS_PARSERS_AND_OPERATORS; + + static + { + JUSS_PARSERS.add(0, new ImportConverter()); + JUSS_PARSERS_AND_OPERATORS = JUSS_PARSERS.clone(); + + try + { + InvokeStaticFunc(Class.forName("org.ugp.serialx.converters.Operators"), "install", JUSS_PARSERS_AND_OPERATORS); + } + catch (Exception e) + {} + } + + protected Imports imports; + + /** + * @deprecated (1.3.9) SET 0b10 BIT OF {@link Serializer#getFormat()} TO 1 INSTEAD IF YOU WANT TO SET THIS ON TRUE. OR SIMPLY USE {@link JussSerializer#setGenerateComments(boolean)} + * + * Set this on true and program will generate comments and report!
+ * Note: Keep this on false to achieve the best performance! + * + * @since 1.0.5 + */ + @Deprecated + protected boolean generateComments = false; + + /** + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Object... values) + { + this(null, values); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Map variablesMap, Object... values) + { + this(variablesMap, values == null ? null : new ArrayList<>(Arrays.asList(values))); + } + + /** + * @param sourceScope | Scope with initial content! + * + * @since 1.3.5 + */ + public JussSerializer(GenericScope sourceScope) + { + this(sourceScope == null ? null : sourceScope.variables(), sourceScope == null ? null : sourceScope.values()); + } + + /** + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Map variablesMap, Collection values) + { + this(null, variablesMap, values); + } + + /** + * @param parsers | Registry of parsers to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * + * @since 1.3.2 + */ + public JussSerializer(Registry parsers, Map variablesMap, Collection values) + { + this(parsers, null, variablesMap, values, null); + } + + /** + * @param parsers | Registry of parsers to use! + * @param protocols | Registry of protocols to use! + * @param variablesMap | Initial variables to be added in to this scope! + * @param values | Initial independent values to be added in to this scope! + * @param parent | Parent of this scope. + * + * @since 1.3.2 + */ + public JussSerializer(Registry parsers, ProtocolRegistry protocols, Map variablesMap, Collection values, Scope parent) + { + super(parsers, protocols, variablesMap, values, parent); + } + + @Override + public JussSerializer emptyClone(Scope parent) + { + JussSerializer srl = emptyClone(new JussSerializer(), parent); + return srl; + } + + @Override + public ParserRegistry getParsers() + { + return parsers != null ? parsers : (parsers = JUSS_PARSERS.clone()); + } + + @Override + public Imports getImports() + { + if (imports == null) + imports = ImportsProvider.IMPORTS.clone(); + return imports; + } + + /** + * @param absoluteClone | If true this scope will be cloned using {@link Utils#Clone}, if false {@link Scope#clone()}! + * + * @return Clone of this scope! + * + * @since 1.3.2 + */ + public Scope clone(boolean absoluteClone) + { + if (absoluteClone) + return Clone(this, getParsers(), new Object[] {this, -9999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); + return super.clone(); + } + + /** + * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! + * + * @param name | Name of variable. + * @param value | Value of variable. + * + * @return Variable in JUSS form to serialize as [name] = [value]. + * + * @since 1.1.5 + */ + @Deprecated + @Override + public String Var(String name, T value) + { + return Var(name, value, false); + } + + /** + * @deprecated (1.3.9) DO NOT USE THIS, USE {@link VariableConverter#NewVariable(String, Object)} OR VARIATION OF {@link AbstractMap.SimpleEntry} INSTEAD! + * + * @param name | Name of variable. + * @param value | Value of variable. + * @param isValue | True if variables value supposed to by visible also during value loading. + * + * @return Variable in JUSS form to serialize as [name] = [value]. + * + * @since 1.1.5 + */ + @Deprecated + public String Var(String name, T value, boolean isValue) + { + return Code((isValue ? "$" : "") + name + " = " + getParsers().toString(value, this, 0, 0, getProtocols(), getFormat()) + (isGenerateComments() ? "; //Object of " + value.getClass().getName() + ": \"" + value + "\" inserted manually! Stored by \"" + name + "\" variable!" : "")); + } + + /** + * @param cls | Class to invoke static member on! + * @param staticMethodName | Name of static member! + * @param args | Arguments of method (use this only if you are invoking method no field)! + * + * @return Static member invocation in JUSS form to serialize as [class]::[method | field] [args]... + *

Note: This will not invoke member from class directly, it will be invoked during unserialization, also no checks are performed here so this will not notify you if member or class does not exist!
+ * Also this will work only in combination {@link ObjectConverter}! + * + * @since 1.2.2 + */ + public String StaticMember(Class cls, String staticMethodName, Object... args) + { + StringBuilder sb = new StringBuilder(cls.getName()).append("::").append(staticMethodName); + for (int i = 0, len = args.length; i < len; i++) + { + sb.append(' '); + + try + { + getParsers().toString(sb, args[i], this, 0, 0, getProtocols(), getFormat()); + } + catch (IOException e) + { + throw new RuntimeException(e); // No... + } + } + return Code(sb); + } + + /** + * @param source | Source {@link Appendable} to serialize variables and objects into! + * @param args | Additional arguments to use, in case of {@link JussSerializer} this should be array of length 6 with 0. argument being this pointer to this serializer, + * argument 1. and 2. being integers signifying number of tabs and index of parsing iteration (used primarily by {@link ObjectConverter}), argument 3. containing {@link ProtocolRegistry} of this {@link Serializer}, + * argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null), + * and argument 5. being byte bit array containing the formating flags ({@link Serializer#getFormat()}) containing the information about if the code comments are supposed to be generated and/or indentation and newline characters inclusion! + * + * @return Source {@link Appendable} with variables and objects serialized in specific format. + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + @Override + public A serializeTo(A source, Object... args) throws IOException + { + Map variables = variables(); + List objs = values(); + int valuesLen = objs.size(), varLen = variables.size(), i = 0, tabs = 0; + boolean generateComments = isGenerateComments(); + + if (args.length < 6) + args = Arrays.copyOf(args, 6); + args[0] = this; + if (args[1] == null) + args[1] = tabs; //tabs + else if (args[1] instanceof Integer) + tabs = (int) args[1]; + if (args[2] == null) + args[2] = 0; //index + if (args[3] == null) + args[3] = getProtocols(); + if (args[5] == null) + args[5] = getFormat(); + + source = source == null ? (A) new StringBuilder() : source; + if (generateComments && varLen + valuesLen > 0) //Gen scope comment + { + if (tabs <= 0) + source.append("//Date created: ").append(new SimpleDateFormat("MM-dd-yyyy 'at' HH:mm:ss z \n\n").format(new Date())); + source.append(multilpy('\t', tabs)).append("//Scope serialization summary:\n"); + if (varLen > 0) + source.append(multilpy('\t', tabs)).append("//").append(varLen+"").append(" variables!\n"); + + if (valuesLen > 0) + source.append(multilpy('\t', tabs)).append("//").append(valuesLen+"").append(" values!\n"); + if (tabs > -1) + source.append('\n'); + } + + ParserRegistry reg = getParsers(); + + if (varLen > 0) + { + if (generateComments) + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); + if (!(var.getValue() instanceof Scope) || ((Scope) var.getValue()).isEmpty()) + GenerateComment(source, reg, var); + + if (++i < varLen || valuesLen > 0) + source.append('\n'); + } + } + else if (format != 0) + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg, var, tabs, i >= varLen-1 && valuesLen <= 0, args); + + if (++i < varLen || valuesLen > 0) + source.append('\n'); + } + } + else // No formating + { + for (Entry var : variables.entrySet()) //Vars + { + appandVar(source, reg, var, tabs, i++ >= varLen-1 && valuesLen <= 0, args); + } + } + } + + if (generateComments) + { + for (i = 0; i < valuesLen; i++) //Values + { + if (i != 0) + source.append('\n'); + + Object obj; + appandVal(source, reg, obj = objs.get(i), tabs, i == valuesLen-1, args); + if (!(obj instanceof Scope) || ((Scope) obj).isEmpty()) + GenerateComment(source, reg, obj); + } + } + else if (format != 0) + { + for (i = 0; i < valuesLen; i++) //Values + { + if (i != 0) + source.append('\n'); + + appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); + } + } + else // No formating + { + for (i = 0; i < valuesLen; i++) //Values + { + appandVal(source, reg, objs.get(i), tabs, i == valuesLen-1, args); + } + } + + if (source instanceof Flushable) + ((Flushable) source).flush(); + if (tabs == 0) + getImports().removeImportsOf(this); + return source; + } + + /** + * his should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) varToSerialize into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + protected Appendable appandVar(Appendable source, ParserRegistry parsersToUse, Entry varToSerialize, int tabs, boolean isLast, Object[] args) throws IOException + { + if (format != 0) + source.append(multilpy('\t', tabs)); + if (parsersToUse.toString(source, varToSerialize, args) == null || isLast) + return source; + return source.append(';'); + } + + /** + * This should stringify and append ({@link ParserRegistry#toString(Appendable, Object, Object...)}) objToSerialize into source based on arguments, add separator and return source! + * + * @since 1.3.2 + */ + protected Appendable appandVal(Appendable source, ParserRegistry parsersToUse, Object objToSerialize, int tabs, boolean isLast, Object[] args) throws IOException + { + if (format != 0) + source.append(multilpy('\t', tabs)); + if (parsersToUse.toString(source, objToSerialize, args) == null || isLast) + return source; + return source.append(';'); + } + + /** + * @return Generated description for obj, appended in source! + * + * @since 1.3.2 + */ + public Appendable GenerateComment(Appendable source, ParserRegistry registry, Object obj) throws IOException + { + try + { + CharSequence comment = registry.getConverterFor(obj).getDescription(registry, obj); + if (comment.length() > 0) + return source.append(" //").append(comment); + } + catch (Exception e) + { + return source.append(" //").append(DataConverter.getDefaultDescriptionFor(obj)); + } + return source; + } + + /** + * @param reader | Reader to read from! + * @param args | Additional arguments to use. In case of JussSerializer, this should be array of length 4 with 0. argument will being this pointer of this serializer, + * 1. and 2. argument are null (they are used by JUSS parsers) and argument 3. will be {@link ProtocolRegistry} used by this {@link Serializer}, + * and additional argument 4. being of type {@link Class} containing information about class that is currently being serialized (used primarily by {@link ObjectConverter} and should start as null). + * + * @return This scope after loading data from reader (you most likely want to return "this")! + * + * @throws IOException When reading the reader fails... + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + @Override + public S loadFrom(Reader reader, Object... args) throws IOException + { +// boolean formatRequired = true; + + if (args.length < 4) + args = Arrays.copyOf(args, 4); +// if (args[0] instanceof Boolean) +// formatRequired = (boolean) args[0]; + args[0] = this; + if (args[3] == null) + args[3] = getProtocols(); + +// StringBuilder str = readAndFormat(reader, formatRequired); +// List objs = splitAndParse(str, args); +// addAll(objs); + + readAndParse(values(), reader, 512, args); + + if (parent == null) + getImports().removeImportsOf(this); + return (S) this; + } + + /** + * This acts basically as reader + lexer for Juss and Json input... + * + * @param result | Resulting collection of objects to fill up with parsed objects from reader. + * @param reader | The reader to {@link Reader#read(char[], int, int)}. + * @param charBuffLen | Length of internal char buffer (number of chars that are processed at once). Recommended length is 512, in case of increase should be the power of 2. + * @param parserArgs | Additional arguments to use. Take a look at {@link Serializer#loadFrom(File, Object...)}. + * + * @throws IOException If {@link Reader} instance throws it during reading... + * + * @since 1.3.9 + */ + public void readAndParse(Collection result, Reader reader, final int charBuffLen, Object... parserArgs) throws IOException + { + ParserRegistry reg = getParsers(); + + StringBuilder sb = new StringBuilder(); + int len; + + char chars[] = new char[charBuffLen], oldCh = 0; + readerLoop: for (int charsRead, /*state = 0,*/ brackets; (charsRead = reader.read(chars, 0, charBuffLen)) != -1; ) + { + charsLoop: for (int i = 0; i < charsRead; i++) + { + char ch = chars[i]; + + if (oldCh == '/') // Skip the comments... + { + if (ch == '/' || ch == '*') // // | /* + { + sb.setLength(len = (sb.length() - 1)); // Pop / and restore old char, important! + oldCh = len == 0 ? 0 : sb.charAt(len - 1); + for (;;) // Skip all till end of comm + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + if (ch == '/' ? + isOneOf(chars[i], ENDL) : + chars[i] == '*' && (++i < charsRead ? chars[i] : reader.read()) == '/' // */ + ) { + continue charsLoop; + } + } + } + } + + if (ch == '\"' || ch == '\'') + { + sb.append(ch); + for (oldCh = ch; ; ) // Append all chars until end of str/char + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + sb.append(ch = chars[i]); + if (ch == oldCh) + continue charsLoop; // break; + } + } + else if ((ch | ' ') == '{') + { + sb.append(ch); + brackets = 1; + do + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + sb.append(ch = chars[i]); + if ((ch |= ' ') == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '\"' || ch == '\'') + { + for (oldCh = ch; ; ) // Append all chars until end of str/char + { + if (++i >= charsRead) // Check and read on if necessary... + if ((charsRead = reader.read(chars, 0, charBuffLen)) != -1) + i = 0; + else break readerLoop; + + sb.append(ch = chars[i]); + if (ch == oldCh) + break; + } + } + } + while (brackets != 0); + } + else if (ch == ';' || ch == ',' || (oldCh == '}' && isOneOf(ch, ENDL))) + { + if ((len = sb.length()) != 0) + { + if (oldCh == ' ') // Trim + sb.setLength(--len); + + if (len != 0) + { +// System.err.println("|" + sb.toString() + "| " + (oldCh == ' ') + "\n"); + Object obj = parseObject(reg, sb.toString(), parserArgs); + if (obj != VOID) + result.add(obj); + sb.setLength(0); + } + } + + oldCh = 0; + continue; + } + else if (ch <= ' ') // Handle blanks, skip unnecessary + { + if (oldCh > ' ') // First blank (in possible row) + sb.append(oldCh /*= state*/ = ' '); + continue; + } + else + sb.append(ch); + + oldCh = ch; + } + } + + if ((len = sb.length()) == 0) + return; + + if (oldCh == ' ') // Trim + sb.setLength(--len); + + if (len != 0) + { +// System.err.println("|" + sb.toString() + "| " + (oldCh) + "\n"); + Object obj = parseObject(reg, sb.toString(), parserArgs); + if (obj != VOID) + result.add(obj); + } + } + + /** + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! + * + * @return Formated content of reader ready to parse! Should not modify this object in any way! + * + * @since 1.3.2 + */ + @Deprecated + public StringBuilder readAndFormat(Reader reader, boolean format) + { + int quote = 0, multLineCom = -1; + //int brackets = 0, lastIndex = 0, delChars = 0; + StringBuilder sb = new StringBuilder(); + + try + { + BufferedReader lineReader = new BufferedReader(reader); + //String blanks = new String(new char[] {32, 9, 10, 12, 13}); + for (String line = lineReader.readLine(); line != null; line = lineReader.readLine()) + { + if (format) + { + int lastNotBlank = -1; + for (int i = 0, com = -1, len = line.length(); i < len; i++) + { + char ch = line.charAt(i); + + boolean notString = quote % 2 == 0; + if (multLineCom > -1 || com > -1) //Is comment + { + if (multLineCom > 0 && ch == '*' && i < len-1 && line.charAt(++i) == '/') + com = multLineCom = -1; + } + else if (notString && ch == '/' && i < len-1) + { + if (line.charAt(i+1) == '*') + i += multLineCom = 1; + else if (line.charAt(i+1) == '/') + com++; + else + sb.append('/'); + } + else if (notString && ch >= 9 && ch <= 13) + sb.append(' '); + else + { + /*if (notString) + { + if (ch | ' ') == '{' || ch == '[') + brackets++; + else if (ch == '}' || ch == ']') + { + if (brackets > 0) + brackets--; + else + throw new IllegalArgumentException("Missing opening bracket in: " + line); + } + else if (brackets == 0 && isOneOf(ch, ';', ',')) + { + System.out.println(sb); + sb = new StringBuilder(); + continue; + } + }*/ + if (ch > 32) + { + lastNotBlank = ch; + if (ch == '"') + quote++; + } + sb.append(ch); + } + } + sb.append((lastNotBlank | ' ') == '}' ? ';' : ' '); + } + else + sb.append(line).append('\n'); + } + lineReader.close(); + } + catch (IOException e) + { + e.printStackTrace(); + } + + return sb; + } + + /** + * @deprecated (1.3.9) DO NOT USE, IT IS SLOW AND POORLY WRITTEN, USE {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)} INSTEAD! + * + * @return List of objects parsed from given formatted string! + * + * @since 1.3.2 + */ + @Deprecated + public List splitAndParse(StringBuilder formattedStr, Object... parserArgs) + { + List result = new ArrayList<>(); + + ParserRegistry reg = getParsers(); + + //DataParser[] parsers = new DataParser[DataParser.REGISTRY.size()]; + int lastIndex = 0, len = formattedStr.length(); + //boolean isBracketSplit = false; + for (int i = 0; i < len; i++) + { + int ch = formattedStr.charAt(i); + if (ch == '"') + { + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + formattedStr); + while (formattedStr.charAt(i) != '"'); + } + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + formattedStr); + if ((ch = (formattedStr.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && formattedStr.charAt(i) != '"'); + } + } + else if ((ch == ';' || ch == ',')/* || (brackets == 1 && (isBracketSplit = ch == '}' || ch == ']'))*/) + { + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, lastIndex = i /*+ (isBracketSplit ? 1 : 0)*/).trim(); + if (!str.isEmpty()) + { +// System.out.println("|" + str + "|\n"); + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); + } + //add = 1; + } + } + + String str = formattedStr.substring(lastIndex == 0 ? 0 : lastIndex + 1, len).trim(); + if (!str.isEmpty()) + { +// System.out.println("|" + str + "|\n"); + Object obj = parseObject(reg, str, parserArgs); + if (obj != VOID) + result.add(obj); + } + return result; + } + +// /** +// * @return Object converted to string! +// *

+// * Note: Used by {@link JussSerializer#SerializeTo(Appendable, Object...)}! +// * +// * @see DataConverter#objToString(Registry, String, Object...) +// * +// * @since 1.3.5 +// */ +// public CharSequence objectToStr(Registry registry, Object obj, Object... parserArgs) +// { +// return +// } + + /** + * @return Object parsed from str! + *

+ * Note: Used by {@link JussSerializer#readAndParse(Collection, Reader, int, Object...)}! + * + * @see ParserRegistry#parse(ParserRegistry, String, Object...) + * + * @since 1.3.2 + */ + protected Object parseObject(ParserRegistry registry, String str, Object... parserArgs) + { + return registry.parse(str, parserArgs); + } + + /** + * @param variableKey | Variable to clone! + * + * @return Clone of value stored by variable with inserted name or null if there is no such a one! + *

+ * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * + * @since 1.3.2 + */ + public T cloneOf(String variableKey) + { + return cloneOf(variableKey, null); + } + + /** + * @param variableKey | Variable to clone! + * @param defaultValue | Default value to return. + * + * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! + *

+ * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * + * @since 1.3.2 + */ + public T cloneOf(String variableKey, T defaultValue) + { + T obj = get(variableKey, defaultValue); + if (obj == defaultValue) + return defaultValue; + return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); + } + + /** + * @param valueIndex | Index of independent value. Also can be negative, in this case u will get elements from back! + * {@link IndexOutOfBoundsException} will be thrown if index is too big! + * + * @return Clone of independent value with valueIndex! + *

+ * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * + * @since 1.3.2 + */ + public T cloneOf(int valueIndex) + { + T obj = get(valueIndex); + return Clone(obj, getParsers(), new Object[] {this, -99999, 0, getProtocols(), getFormat()}, this, null, null, getProtocols()); + } + + /** + * @return True if comment supposed to be generated! + * + * @since 1.3.2 + */ + public boolean isGenerateComments() + { + return (format & 0b10) != 0; + } + + /** + * @param generateComments | If true, comments will be generated during serialization! + * + * @since 1.3.2 + */ + public void setGenerateComments(boolean generateComments) + { + if (generateComments) + format |= 0b10; + else + format &= 0xff ^ 0b10; + } + +// /** +// * @return True if used parsers and converters are cached during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! +// * +// * @since 1.3.5 +// * +// * @see ParserRegistry#resetCache() +// */ +// public boolean isSerializationAutoCaching() +// { +// return serializationAutoCaching; +// } +// +// /** +// * @param serializationAutoCaching | Set this on true to allow caching of used parsers and converters during individual serializations and deserializations! This can improve performance a lot but in some cases might cause some strange artifacts! +// * +// * @since 1.3.5 +// * +// * @see ParserRegistry#resetCache() +// * @see ParserRegistry#destroyCache() +// */ +// public void setSerializationAutoCaching(boolean serializationAutoCaching) +// { +// if (!(this.serializationAutoCaching = serializationAutoCaching)) +// getParsers().destroyCache(); +// } + + /** + * @param fromObj | Object to create serializer from! + * + * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JussSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception If something went wrong during deserialization! + * + * @since 1.3.5 + */ + public static JussSerializer from(Object fromObj) throws Exception + { + try + { + return from(fromObj, new String[0]); + } + catch (IntrospectionException e) + { + return new JussSerializer(fromObj); + } + } + + /** + * @param fromObj | Object to create serializer from! + * @param fieldNamesToUse | Array of obj field names to map into scopes variables using getters (read method)! {@link PropertyDescriptor}s of these fields will be obtained using {@link Scope#getPropertyDescriptorsOf(Class, String...)}! This is used only as a last (default) option! + * + * @return {@link JussSerializer} created from given fromObj by mapping obj's fields into variables of created serializer via given fields (fieldNamesToUse) and conversion rules listed below!!

+ * Table of specific Object --> JussSerializer conversions: + * + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Object (fromObj) typeObtained serializer content (return)
{@link CharSequence}{@link Serializer#loadFrom(CharSequence, Object...)}
{@link CharSequence} (as http address)Serializer (newInstance) will open connection with url and get + deserialize the content from it if possible!
{@link File}{@link Serializer#loadFrom(File, Object...)}
{@link Reader}{@link Serializer#loadFrom(Reader)}
{@link InputStream}{@link Serializer#loadFrom(InputStream, Object...)}
{@link URL}Serializer (newInstance) will open connection with {@link URL} and get + deserialize the content from it if possible!
{@link URLConnection}Serializer (newInstance) will attempt to get + deserialize the content from given {@link URLConnection} if possible!
Others (default){@link Scope#from(Object, String...)} (return description)
+ * + * @throws Exception if calling of some {@link PropertyDescriptor}s write method fails (should not happen often) or when something went wrong during deserialization! + * @throws IntrospectionException when there were no PropertyDescriptor found for obj class! + * + * @since 1.3.5 + */ + public static JussSerializer from(Object fromObj, String... fieldNamesToUse) throws IntrospectionException, Exception + { + return (JussSerializer) Serializer.from(new JussSerializer(), fromObj, fieldNamesToUse); + } +} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 9deb550..958aabc 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -1,181 +1,181 @@ -package org.ugp.serialx.juss.converters; - -import static org.ugp.serialx.utils.Utils.castArray; -import static org.ugp.serialx.utils.Utils.fromAmbiguousArray; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.splitValues; - -import java.io.IOException; - -import org.ugp.serialx.converters.DataConverter; - -/** - * This converter is capable of converting primitive arrays. - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - - - - - - - - - - - - - - - - - - -
StringObject
1 2 3new int[] {1, 2, 3}
4 5 "hello!"new Object[] {4, 5, "hello!"}
"Lorem" "ipsum"new String[] {"Lorem", "ipsum"}
- *
- * This parser requires one optional parse method arg that is type of boolean at index 1 and it specifies if resolving datatype of a parsed array is required (default true). - * - * @author PETO - * - * @since 1.3.0 - */ -public class ArrayConverter implements DataConverter -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len, startI = 0; - if ((len = str.length()) != 0 && str.charAt(0) == '@' || (startI = indexOfNotInObj(str, 1, len, 0, true, ' ')) > 0) - { - String[] strObjs = tokenize(startI == 0 ? str.substring(1).trim() : str, startI); - int arrLen, i = 0; - Object[] arr = new Object[arrLen = strObjs.length]; - - if (args.length < 2 || !(args[1] instanceof Boolean) || (boolean) args[1]) - { - Class arrClass = null; - for (; i < arrLen; i++) - { - Object obj = arr[i] = myHomeRegistry.parse(strObjs[i], args); - if (obj != null) - if (arrClass == null) - arrClass = obj.getClass(); - else if (arrClass != obj.getClass()) - arrClass = Object.class; - } - - if (arrClass != null && arrClass != Object.class) - try - { - return castArray(arr, arrClass); - } - catch (IllegalArgumentException e) - {} - return arr; - } - - for (; i < arrLen; i++) - arr[i] = myHomeRegistry.parse(strObjs[i], args); - return arr; - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj != null && myHomeRegistry != null && obj.getClass().isArray()) - { - int index = args.length > 2 && args[2] instanceof Integer ? (int) args[2] : 0; - - if (index <= 0 || myHomeRegistry.indexOf(OperationGroups.class) > -1) - { - int tabs; - - if (args.length > 2) - { - tabs = args[1] instanceof Integer ? (int) args[1] : 0; - - args = args.clone(); //Necessary for preventing this from affecting other objects and arrays... - args[2] = index + 1; - } - else - tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; - - Object[] elms = fromAmbiguousArray(obj); - final int len = elms.length; - if (len == 0) - return source.append('@'); - source.append(index > 0 ? "(@" : "@"); - - StringBuilder elmStr = new StringBuilder(); - if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) // Format - { - for (int i = 0; i < len; i++) - { - if (i != 0 && i % 1000 == 0) - { - source.append('\n'); - for (int j = 0; j < tabs+1; j++) - source.append('\t'); - } - else - source.append(' '); - - elmStr.setLength(0); - myHomeRegistry.toString(elmStr, elms[i], args); - char ch = elmStr.charAt(0); - if ((ch | ' ') == '{') - source.append('(').append(elmStr).append(')'); - else - source.append(elmStr); - } - } - else - { - for (int i = 0; i < len; i++) - { - source.append(' '); - - elmStr.setLength(0); - myHomeRegistry.toString(elmStr, elms[i], args); - char ch = elmStr.charAt(0); - if ((ch | ' ') == '{') - source.append('(').append(elmStr).append(')'); - else - source.append(elmStr); - } - } - - return index > 0 ? source.append(')') : source; - } - } - return CONTINUE; - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) - { - return "Primitive array " + objToDescribe + " converted by " + getClass().getName(); - } - - /** - * @param str | String to tokenize! - * @param firstSplitterI | Index of first expected splitter char (space). - * - * @return String splitted according to defined rules! - * - * @since 1.3.2 - */ - public String[] tokenize(String str, int firstSplitterI) - { - return str.isEmpty() ? new String[0] : splitValues(str, firstSplitterI, 0, 2, new char[0], ' '); - } +package org.ugp.serialx.juss.converters; + +import static org.ugp.serialx.utils.Utils.castArray; +import static org.ugp.serialx.utils.Utils.fromAmbiguousArray; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.splitValues; + +import java.io.IOException; + +import org.ugp.serialx.converters.DataConverter; + +/** + * This converter is capable of converting primitive arrays. + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + + + + + + + + + + + + + + + + + + +
StringObject
1 2 3new int[] {1, 2, 3}
4 5 "hello!"new Object[] {4, 5, "hello!"}
"Lorem" "ipsum"new String[] {"Lorem", "ipsum"}
+ *
+ * This parser requires one optional parse method arg that is type of boolean at index 1 and it specifies if resolving datatype of a parsed array is required (default true). + * + * @author PETO + * + * @since 1.3.0 + */ +public class ArrayConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len, startI = 0; + if ((len = str.length()) != 0 && str.charAt(0) == '@' || (startI = indexOfNotInObj(str, 1, len, 0, true, ' ')) > 0) + { + String[] strObjs = tokenize(startI == 0 ? str.substring(1).trim() : str, startI); + int arrLen, i = 0; + Object[] arr = new Object[arrLen = strObjs.length]; + + if (args.length < 2 || !(args[1] instanceof Boolean) || (boolean) args[1]) + { + Class arrClass = null; + for (; i < arrLen; i++) + { + Object obj = arr[i] = myHomeRegistry.parse(strObjs[i], args); + if (obj != null) + if (arrClass == null) + arrClass = obj.getClass(); + else if (arrClass != obj.getClass()) + arrClass = Object.class; + } + + if (arrClass != null && arrClass != Object.class) + try + { + return castArray(arr, arrClass); + } + catch (IllegalArgumentException e) + {} + return arr; + } + + for (; i < arrLen; i++) + arr[i] = myHomeRegistry.parse(strObjs[i], args); + return arr; + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj != null && myHomeRegistry != null && obj.getClass().isArray()) + { + int index = args.length > 2 && args[2] instanceof Integer ? (int) args[2] : 0; + + if (index <= 0 || myHomeRegistry.indexOf(OperationGroups.class) > -1) + { + int tabs; + + if (args.length > 2) + { + tabs = args[1] instanceof Integer ? (int) args[1] : 0; + + args = args.clone(); //Necessary for preventing this from affecting other objects and arrays... + args[2] = index + 1; + } + else + tabs = args.length > 1 && args[1] instanceof Integer ? (int) args[1] : 0; + + Object[] elms = fromAmbiguousArray(obj); + final int len = elms.length; + if (len == 0) + return source.append('@'); + source.append(index > 0 ? "(@" : "@"); + + StringBuilder elmStr = new StringBuilder(); + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) // Format + { + for (int i = 0; i < len; i++) + { + if (i != 0 && i % 1000 == 0) + { + source.append('\n'); + for (int j = 0; j < tabs+1; j++) + source.append('\t'); + } + else + source.append(' '); + + elmStr.setLength(0); + myHomeRegistry.toString(elmStr, elms[i], args); + char ch = elmStr.charAt(0); + if ((ch | ' ') == '{') + source.append('(').append(elmStr).append(')'); + else + source.append(elmStr); + } + } + else + { + for (int i = 0; i < len; i++) + { + source.append(' '); + + elmStr.setLength(0); + myHomeRegistry.toString(elmStr, elms[i], args); + char ch = elmStr.charAt(0); + if ((ch | ' ') == '{') + source.append('(').append(elmStr).append(')'); + else + source.append(elmStr); + } + } + + return index > 0 ? source.append(')') : source; + } + } + return CONTINUE; + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Primitive array " + objToDescribe + " converted by " + getClass().getName(); + } + + /** + * @param str | String to tokenize! + * @param firstSplitterI | Index of first expected splitter char (space). + * + * @return String splitted according to defined rules! + * + * @since 1.3.2 + */ + public String[] tokenize(String str, int firstSplitterI) + { + return str.isEmpty() ? new String[0] : splitValues(str, firstSplitterI, 0, 2, new char[0], ' '); + } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java index 7c50205..ceb203e 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ImportConverter.java @@ -1,81 +1,81 @@ -package org.ugp.serialx.juss.converters; - -import java.io.IOException; - -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.imports.Import; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.converters.imports.ImportsProvider.Imports; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! - * Parsing example: import java.util.ArrayList will add temporary {@link Import} of java.util.ArrayList or java.lang.String => Word will import java.lang.String as Word! - * Imports will be converted to string just by calling toString!
- *
- * This parser requires additional parser arg at index 0 of type {@link ImportsProvider} that will obtain managed imports! This arg is required during both parsing and converting! - * - * @author PETO - * - * @since 1.3.0 - */ -public class ImportConverter implements DataConverter -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (args.length > 0 && args[0] instanceof ImportsProvider) - { - Imports imports = ((ImportsProvider) args[0]).getImports(); - int index; - if (str.startsWith("import ")) - { - try - { - if ((str = str.substring(7).trim()).indexOf("=>") > -1) - return parse(myHomeRegistry, str, args); - imports.add(new Import(imports.forName(str), (ImportsProvider) args[0])); - } - catch (ClassNotFoundException e) - { - LogProvider.instance.logErr("Unable to import " + str + " because there is no such a class!", e); - } - return VOID; - } - else if ((index = (str = str.trim()).indexOf("=>")) > -1) - { - try - { - imports.add(new Import(imports.forName(str.substring(0, index).trim()), str.substring(index+2).trim(), (ImportsProvider) args[0])); - } - catch (ClassNotFoundException e) - { - LogProvider.instance.logErr("Unable to import " + str.substring(0, index).trim() + " because there is no such a class!", e); - } - catch (Exception e2) - { - LogProvider.instance.logErr(e2.getMessage(), e2); - } - return VOID; - } - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) - { - return source.append(obj.toString()); - } - return CONTINUE; - } - - @Override - public String getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) - { - return "Import of " + ((Import) objToDescribe).getCls() + " as " + ((Import) objToDescribe).getClsAlias(); - } +package org.ugp.serialx.juss.converters; + +import java.io.IOException; + +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.imports.Import; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.converters.imports.ImportsProvider.Imports; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser maintains list of {@link Imports#IMPORTS} represented as {@link Import}s. Where are registered imports imported by user as well as temporary imports that are parsed! Result of parsing will be always added to imports list and {@link DataParser#VOID} will be returned! + * Parsing example: import java.util.ArrayList will add temporary {@link Import} of java.util.ArrayList or java.lang.String => Word will import java.lang.String as Word! + * Imports will be converted to string just by calling toString!
+ *
+ * This parser requires additional parser arg at index 0 of type {@link ImportsProvider} that will obtain managed imports! This arg is required during both parsing and converting! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ImportConverter implements DataConverter +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (args.length > 0 && args[0] instanceof ImportsProvider) + { + Imports imports = ((ImportsProvider) args[0]).getImports(); + int index; + if (str.startsWith("import ")) + { + try + { + if ((str = str.substring(7).trim()).indexOf("=>") > -1) + return parse(myHomeRegistry, str, args); + imports.add(new Import(imports.forName(str), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str + " because there is no such a class!", e); + } + return VOID; + } + else if ((index = (str = str.trim()).indexOf("=>")) > -1) + { + try + { + imports.add(new Import(imports.forName(str.substring(0, index).trim()), str.substring(index+2).trim(), (ImportsProvider) args[0])); + } + catch (ClassNotFoundException e) + { + LogProvider.instance.logErr("Unable to import " + str.substring(0, index).trim() + " because there is no such a class!", e); + } + catch (Exception e2) + { + LogProvider.instance.logErr(e2.getMessage(), e2); + } + return VOID; + } + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (args.length > 0 && args[0] instanceof ImportsProvider && obj instanceof Import) + { + return source.append(obj.toString()); + } + return CONTINUE; + } + + @Override + public String getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + return "Import of " + ((Import) objToDescribe).getCls() + " as " + ((Import) objToDescribe).getClsAlias(); + } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 5d79fa7..1c45de5 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -1,193 +1,193 @@ -package org.ugp.serialx.juss.converters; - -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; - -import java.io.IOException; -import java.io.StringReader; -import java.util.Arrays; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.Serializer; -import org.ugp.serialx.converters.ProtocolConverter; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.juss.JussSerializer; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; -import org.ugp.serialx.utils.LogProvider; - -/** - * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! - * This is also responsible for {@link Scope}! - * Its case sensitive! - *
- *
- * Table of sample string <--> object conversions: - * - - - - - - - - - - - - - - - - - -
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
{ ... }new Scope( ... )
java.lang.Math::max 10 510
- Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
-
- This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
- This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
- * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
- * - * @author PETO - * - * @since 1.3.0 - */ -public class ObjectConverter extends ProtocolConverter -{ - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) - { - int len; - if ((len = str.length()) > 0) - { - boolean hasOp, hasCls; - if ((hasOp = (str.charAt(0) | ' ') == '{') && (hasCls = (str.charAt(len-1) | ' ') == '}')) // Unwrap if wrapped in {} - len = (str = str.substring(1, --len).trim()).length(); - else - hasCls = false; - - Class objClass; - int chI; -// if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || indexOfNotInObj(str, chI, len, -1, true, "==", "::") != -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) - if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || ++chI < len && str.charAt(chI) == ':' && indexOfNotInObj(str, ++chI, len, -1, true, ';', ',', '=') == -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) // Is protocol expr in disguise (I know I know but come up with something better before judging...) - return parse(myHomeRegistry, objClass, str, compilerArgs); - - if (hasOp && hasCls) //Is scope - { - Serializer scope; - try //Create desired new empty instance of scope/serializer - { - if (compilerArgs.length > 0 && compilerArgs[0] instanceof Serializer) - { - if (compilerArgs.length > 4 && compilerArgs[4] instanceof Class && Serializer.class.isAssignableFrom((Class) compilerArgs[4])) - scope = ((Serializer) compilerArgs[0]).emptyClone((Class) compilerArgs[4], (GenericScope) compilerArgs[0]); - else - scope = ((Serializer) compilerArgs[0]).emptyClone(); - } - else - scope = getPreferredSerializer(); - } - catch (Exception e) - { - scope = getPreferredSerializer(); - } - - if (compilerArgs.length > 0) - { - compilerArgs = compilerArgs.clone(); - compilerArgs[0] = false; //No extra formating... - } - - if (str.isEmpty()) - return scope; - try - { - return scope.loadFrom(new StringReader(str), compilerArgs); - } - catch (IOException e) - { - LogProvider.instance.logErr("Unable to parse the scope because:", e); // Should not occur... - } - } - } - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - return toString(source, myHomeRegistry, obj, null, args); - } - - @SuppressWarnings("unchecked") - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) - { - if (obj instanceof Scope) - { - Serializer serializer; - try - { - if (obj instanceof Serializer) - serializer = (Serializer) obj; - else if (args.length > 0 && args[0] instanceof Serializer) - (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) obj); - else - serializer = getPreferredSerializer(); - } - catch (Exception e) - { - serializer = getPreferredSerializer(); - } - - if (args.length < 6) - args = Arrays.copyOf(args, 6); - else - { - if (args[5] instanceof Byte) - serializer.setFormat((byte) args[5]); - - args = args.clone(); - } - args[2] = 0; - args[3] = serializer.getProtocols(); - - try - { - GenericScope parent; - if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) - source.append(ImportsProvider.getAliasFor(serializer, getClass())).append(' '); - return serializer.serializeAsSubscope(source, args); - } - catch (IOException e) - { - throw new RuntimeException(e); - } - } - - return super.toString(source, myHomeRegistry, obj, preferedProtocol, args); - } - - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) - { - if (obj instanceof Scope && ((Scope) obj).isEmpty()) - return "Empty scope!"; - return super.getDescription(myHomeRegistry, obj, argsUsedConvert); - } - - /** - * @return Serializer that is supposed to be used for serializing sub-scopes if there is no other option. This should never return null! - * - * @since 1.3.5 - */ - public Serializer getPreferredSerializer() - { - return new JussSerializer(); - } +package org.ugp.serialx.juss.converters; + +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Arrays; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.Serializer; +import org.ugp.serialx.converters.ProtocolConverter; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.juss.JussSerializer; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; +import org.ugp.serialx.utils.LogProvider; + +/** + * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! + * This is also responsible for {@link Scope}! + * Its case sensitive! + *
+ *
+ * Table of sample string <--> object conversions: + * + + + + + + + + + + + + + + + + + +
StringObject
ArrayList 2 4 6new ArrayList<>(Arrays.asList(2, 4, 6))
{ ... }new Scope( ... )
java.lang.Math::max 10 510
+ Note: Be aware that invocation of static members such as functions and fields (:: operator) is disabled by default for the sake of security...
+
+ This parser requires additional parser arg at index 0 of type {@link GenericScope} or {@link Serializer} that will be used for further parsing and operating (default new {@link JussSerializer}).
+ This parser requires additional parser arg at index 3 of type {@link ProtocolRegistry} or {@link SerializationProtocol} itself that will be used for parsing protocol expressions (default {@link SerializationProtocol#REGISTRY}).
+ * This parser will insert one additional argument into array of additional parser args at index 4, in case of serialization index 5, that will be of type {@link Class} and it will contains information about class of object that is being unserialized or serialized using protocol!
+ * + * @author PETO + * + * @since 1.3.0 + */ +public class ObjectConverter extends ProtocolConverter +{ + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... compilerArgs) + { + int len; + if ((len = str.length()) > 0) + { + boolean hasOp, hasCls; + if ((hasOp = (str.charAt(0) | ' ') == '{') && (hasCls = (str.charAt(len-1) | ' ') == '}')) // Unwrap if wrapped in {} + len = (str = str.substring(1, --len).trim()).length(); + else + hasCls = false; + + Class objClass; + int chI; +// if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || indexOfNotInObj(str, chI, len, -1, true, "==", "::") != -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) + if (((chI = indexOfNotInObj(str, '=', ':', ';', ',')) == -1 || ++chI < len && str.charAt(chI) == ':' && indexOfNotInObj(str, ++chI, len, -1, true, ';', ',', '=') == -1) && (objClass = getProtocolExprClass(str, compilerArgs)) != null) // Is protocol expr in disguise (I know I know but come up with something better before judging...) + return parse(myHomeRegistry, objClass, str, compilerArgs); + + if (hasOp && hasCls) //Is scope + { + Serializer scope; + try //Create desired new empty instance of scope/serializer + { + if (compilerArgs.length > 0 && compilerArgs[0] instanceof Serializer) + { + if (compilerArgs.length > 4 && compilerArgs[4] instanceof Class && Serializer.class.isAssignableFrom((Class) compilerArgs[4])) + scope = ((Serializer) compilerArgs[0]).emptyClone((Class) compilerArgs[4], (GenericScope) compilerArgs[0]); + else + scope = ((Serializer) compilerArgs[0]).emptyClone(); + } + else + scope = getPreferredSerializer(); + } + catch (Exception e) + { + scope = getPreferredSerializer(); + } + + if (compilerArgs.length > 0) + { + compilerArgs = compilerArgs.clone(); + compilerArgs[0] = false; //No extra formating... + } + + if (str.isEmpty()) + return scope; + try + { + return scope.loadFrom(new StringReader(str), compilerArgs); + } + catch (IOException e) + { + LogProvider.instance.logErr("Unable to parse the scope because:", e); // Should not occur... + } + } + } + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + return toString(source, myHomeRegistry, obj, null, args); + } + + @SuppressWarnings("unchecked") + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) + { + if (obj instanceof Scope) + { + Serializer serializer; + try + { + if (obj instanceof Serializer) + serializer = (Serializer) obj; + else if (args.length > 0 && args[0] instanceof Serializer) + (serializer = ((Serializer) args[0]).emptyClone()).addAll((GenericScope) obj); + else + serializer = getPreferredSerializer(); + } + catch (Exception e) + { + serializer = getPreferredSerializer(); + } + + if (args.length < 6) + args = Arrays.copyOf(args, 6); + else + { + if (args[5] instanceof Byte) + serializer.setFormat((byte) args[5]); + + args = args.clone(); + } + args[2] = 0; + args[3] = serializer.getProtocols(); + + try + { + GenericScope parent; + if ((parent = serializer.getParent()) == null || serializer.getClass() != parent.getClass()) + source.append(ImportsProvider.getAliasFor(serializer, getClass())).append(' '); + return serializer.serializeAsSubscope(source, args); + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } + + return super.toString(source, myHomeRegistry, obj, preferedProtocol, args); + } + + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object obj, Object... argsUsedConvert) + { + if (obj instanceof Scope && ((Scope) obj).isEmpty()) + return "Empty scope!"; + return super.getDescription(myHomeRegistry, obj, argsUsedConvert); + } + + /** + * @return Serializer that is supposed to be used for serializing sub-scopes if there is no other option. This should never return null! + * + * @since 1.3.5 + */ + public Serializer getPreferredSerializer() + { + return new JussSerializer(); + } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 1314bf5..06a5225 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -1,190 +1,190 @@ -package org.ugp.serialx.juss.converters; - -import static org.ugp.serialx.utils.Utils.isOneOf; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides ability to use expression groups that can define order of expression evaluation and compilation! - * Its usage depends on combination with other parsers especially operators! - * Its case sensitive! - *
- *
- * For example: (5 + 5) / 2 = 5 which is different than 5 + 5 / 2 = 7 - *
- * This protocol will insert one additional argument into array of additional parsing args at index 2 that will be of type {@link Map} and it will contains informations about encapsulated groups, do not alter this map in any way unless you know what are you doing! - * - * @author PETO - * - * @since 1.3.0 - */ -public class OperationGroups implements DataParser -{ - /** - * Character marking the opening of {@link OperationGroups} mark in processed string, closing should be marked as this character -1.
- * This character is generated in sami-random fashion but it will never be an ASCII character. - * - * @since 1.3.8 - */ - protected final char groupMark = (char) (System.nanoTime() | 128); - - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - if (str.length() > 1) - { - int opIndex = indexOfOpening(str, 0, '('), clsIndex; - if (opIndex > -1 && (clsIndex = indexOfClosing(str, opIndex, new char[] {'('}, ')')) > -1) - { - Map runtimeGroups; - if (args.length > 2 && args[2] instanceof Map) - runtimeGroups = (Map) args[2]; - else - { - if (args.length < 3) - args = Arrays.copyOf(args, 3); - args[2] = runtimeGroups = new HashMap<>(); - } - - int groupId; - runtimeGroups.put(groupId = runtimeGroups.size(), str.substring(opIndex+1, clsIndex).trim()); - - StringBuilder newStr = new StringBuilder(str).replace(opIndex, clsIndex+1, new StringBuilder().append(groupMark).append(groupId).append((char) (groupMark-1)).toString()); - return myHomeRegistry.parse(newStr.toString(), args); - } - - int groupId; - if ((groupId = isGroupMark(str, groupMark)) != -1) - { - if (args.length > 2 && args[2] instanceof Map) - { - Map runtimeGroups = (Map) args[2]; - - Object[] newArgs = args.clone(); - newArgs[2] = new HashMap(); - return myHomeRegistry.parse(runtimeGroups.get(groupId), newArgs); - } - LogProvider.instance.logErr("Runtime group stack is trying to be accessed using " + str + " however it was not provided yet!", null); - return null; - } - } - - return CONTINUE; - } - - /** - * @param s | Char sequence to check! - * @param groupMark | Opening character identifying this group mark, closing should be this character -1 - * - * @return Id of the group mark if inserted CharSequence matches the runtime group mark wrapper format! -1 otherwise.
- * This is used for internal purposes of {@link OperationGroups}. - * - * @since 1.3.0 - */ - public static int isGroupMark(CharSequence s, char groupMark) - { - int i = s.length()-1; - if (i < 2 || s.charAt(0) != groupMark-- || s.charAt(i--) != groupMark) - return -1; - - int groupId; - if ((groupId = s.charAt(i--) - '0') < 0 || groupId > 9) - return -1; - for (int ch, baseCof = 10; i >= 1; i--, baseCof *= 10) - { - if ((ch = s.charAt(i)) < '0' || ch > '9') - return -1; - groupId += (ch - '0') * baseCof; - } - - return groupId; - } - - /** - * @param str | CharSequence to search! - * @param from | Beginning index of search! - * @param openings | Openings to find! - * - * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! - * - * @since 1.3.0 - */ - public static int indexOfOpening(CharSequence str, int from, char... openings) - { - for (int len = str.length(); from < len; from++) - { - int ch = str.charAt(from); - if (ch == '"') - while (++from < len && str.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); - if ((ch = (str.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < len && str.charAt(from) != '"'); - } - } - else if (isOneOf(ch, openings)) - return from; - } - return -1; - } - - /** - * @param str | CharSequence to search! - * @param from | Beginning index of search! - * @param openings | Openings to count with! - * @param closing | Closings to find! - * - * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! - * - * @since 1.3.0 - */ - public static int indexOfClosing(CharSequence str, int from, char[] openings, char... closing) - { - for (int len = str.length(), ops = 0; from < len; from++) - { - int ch = str.charAt(from); - if (ch == '"') - while (++from < len && str.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); - if ((ch = (str.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < len && str.charAt(from) != '"'); - } - } - else - { - if (isOneOf(ch, openings)) - ops++; - else if (isOneOf(ch, closing)) - { - if (ops == 1) - return from; - ops--; - } - } - } - return -1; - } -} +package org.ugp.serialx.juss.converters; + +import static org.ugp.serialx.utils.Utils.isOneOf; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides ability to use expression groups that can define order of expression evaluation and compilation! + * Its usage depends on combination with other parsers especially operators! + * Its case sensitive! + *
+ *
+ * For example: (5 + 5) / 2 = 5 which is different than 5 + 5 / 2 = 7 + *
+ * This protocol will insert one additional argument into array of additional parsing args at index 2 that will be of type {@link Map} and it will contains informations about encapsulated groups, do not alter this map in any way unless you know what are you doing! + * + * @author PETO + * + * @since 1.3.0 + */ +public class OperationGroups implements DataParser +{ + /** + * Character marking the opening of {@link OperationGroups} mark in processed string, closing should be marked as this character -1.
+ * This character is generated in sami-random fashion but it will never be an ASCII character. + * + * @since 1.3.8 + */ + protected final char groupMark = (char) (System.nanoTime() | 128); + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + if (str.length() > 1) + { + int opIndex = indexOfOpening(str, 0, '('), clsIndex; + if (opIndex > -1 && (clsIndex = indexOfClosing(str, opIndex, new char[] {'('}, ')')) > -1) + { + Map runtimeGroups; + if (args.length > 2 && args[2] instanceof Map) + runtimeGroups = (Map) args[2]; + else + { + if (args.length < 3) + args = Arrays.copyOf(args, 3); + args[2] = runtimeGroups = new HashMap<>(); + } + + int groupId; + runtimeGroups.put(groupId = runtimeGroups.size(), str.substring(opIndex+1, clsIndex).trim()); + + StringBuilder newStr = new StringBuilder(str).replace(opIndex, clsIndex+1, new StringBuilder().append(groupMark).append(groupId).append((char) (groupMark-1)).toString()); + return myHomeRegistry.parse(newStr.toString(), args); + } + + int groupId; + if ((groupId = isGroupMark(str, groupMark)) != -1) + { + if (args.length > 2 && args[2] instanceof Map) + { + Map runtimeGroups = (Map) args[2]; + + Object[] newArgs = args.clone(); + newArgs[2] = new HashMap(); + return myHomeRegistry.parse(runtimeGroups.get(groupId), newArgs); + } + LogProvider.instance.logErr("Runtime group stack is trying to be accessed using " + str + " however it was not provided yet!", null); + return null; + } + } + + return CONTINUE; + } + + /** + * @param s | Char sequence to check! + * @param groupMark | Opening character identifying this group mark, closing should be this character -1 + * + * @return Id of the group mark if inserted CharSequence matches the runtime group mark wrapper format! -1 otherwise.
+ * This is used for internal purposes of {@link OperationGroups}. + * + * @since 1.3.0 + */ + public static int isGroupMark(CharSequence s, char groupMark) + { + int i = s.length()-1; + if (i < 2 || s.charAt(0) != groupMark-- || s.charAt(i--) != groupMark) + return -1; + + int groupId; + if ((groupId = s.charAt(i--) - '0') < 0 || groupId > 9) + return -1; + for (int ch, baseCof = 10; i >= 1; i--, baseCof *= 10) + { + if ((ch = s.charAt(i)) < '0' || ch > '9') + return -1; + groupId += (ch - '0') * baseCof; + } + + return groupId; + } + + /** + * @param str | CharSequence to search! + * @param from | Beginning index of search! + * @param openings | Openings to find! + * + * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! + * + * @since 1.3.0 + */ + public static int indexOfOpening(CharSequence str, int from, char... openings) + { + for (int len = str.length(); from < len; from++) + { + int ch = str.charAt(from); + if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } + } + else if (isOneOf(ch, openings)) + return from; + } + return -1; + } + + /** + * @param str | CharSequence to search! + * @param from | Beginning index of search! + * @param openings | Openings to count with! + * @param closing | Closings to find! + * + * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! + * + * @since 1.3.0 + */ + public static int indexOfClosing(CharSequence str, int from, char[] openings, char... closing) + { + for (int len = str.length(), ops = 0; from < len; from++) + { + int ch = str.charAt(from); + if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } + } + else + { + if (isOneOf(ch, openings)) + ops++; + else if (isOneOf(ch, closing)) + { + if (ops == 1) + return from; + ops--; + } + } + } + return -1; + } +} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 558f5dc..0f5287d 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,269 +1,269 @@ -package org.ugp.serialx.juss.converters; - -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.splitValues; - -import java.io.IOException; -import java.util.AbstractMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.converters.DataConverter; -import org.ugp.serialx.converters.VariableParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using $!
- * {@link VariableConverter#parse} requires one additional Scope argument in args... at index 0!
- * It manages assign operator = as well as access member operator also known as separator ".".
- * Its case sensitive!
- * Exact outputs of this converter are based on inserted scope! - * - * @author PETO - * - * @since 1.3.0 - * - * @see VariableParser - */ -public class VariableConverter extends VariableParser implements DataConverter -{ - @Deprecated - protected boolean jsonStyle; - - public VariableConverter() - { - this(false); - } - - /** - * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * ORMATING IS NO DONE IN toString FUNCTION! - * - * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! - * - * @since 1.3.2 - */ - @Deprecated - public VariableConverter(boolean jsonStyle) - { - setJsonStyle(jsonStyle); - } - - /** - * Raw example of empty variable entry this converter can convert! - * - * @since 1.3.0 - */ - public static final Entry RAW_VAR_ENTRY = NewVariable("", "null"); - - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) - { - if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) - { - GenericScope scope = (GenericScope) args[0]; - int op0Index; - if ((op0Index = isVarAssignment(arg)) > -1) - { - boolean getValueModif = arg.charAt(0) == '$', genericVar = args.length > 4 && args[4] == GenericScope.class; - if (getValueModif) - { - arg = arg.substring(1); - op0Index--; - } - - String vars[] = splitValues(arg, op0Index, 0, 1, new char[] {'?', '<', '>', '!'}, '=', ':'), valStr; - - Object val = null; - int iVal = vars.length-1; - if (vars.length > 1 && !(valStr = vars[iVal]).isEmpty()) - { - val = myHomeRegistry.parse(valStr, args); - } - - eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... Yea this is not the prettiest code but it does the job and mainly it does it fast so shut up! - { - String var = vars[i]; - if (!genericVar) - { - if (contains(var, ' ')) - { - LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); - continue; - } - - if ((op0Index = var.indexOf('.')) > -1) - { - String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); - int iLast = path.length-1, j = 0; - - backlook: do - { - Object sc; - if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... - { - for (j = 1; j < iLast; j++) // Subscope/forward lookup (inner path only)... - if ((sc = getMemberOperator(sc, path[j])) == null || sc == VOID) - break backlook; - - setMemberOperator(myHomeRegistry, sc, path[iLast], val, false, args); - continue eachVar; - } - } - while ((scope = scope.getParent()) != null); - - LogProvider.instance.logErr("Path \"" + var + "\" cannot be set to \"" + val + "\" because \"" + path[j] + "\" is not a accessible or does not exist!", null); - continue; - } - } - - setMemberOperator(myHomeRegistry, scope, var, val, genericVar, args); - } - - return getValueModif ? val : VOID; - } - - return parse(myHomeRegistry, arg, scope, args); //Reading vars from scope... - } - - return CONTINUE; - } - - @Override - public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException - { - if (obj instanceof Entry) - { - Entry var = (Entry) obj; - - final Object key, val = var.getValue(); - if ((key = var.getKey()) instanceof String) - source.append((String) key); - else // We are likely GenericScope - myHomeRegistry.toString(source, key, args); - - if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) - source.append(" = "); - else - source.append('='); - - return myHomeRegistry.toString(source, val, args); - } - return CONTINUE; - } - - @SuppressWarnings("unchecked") - @Override - public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) - { - Entry ent = (Entry) objToDescribe; - return new StringBuilder(myHomeRegistry.getConverterFor(ent.getValue(), argsUsedConvert).getDescription(myHomeRegistry, ent.getValue(), argsUsedConvert)).append(" Stored by \"").append(ent.getKey()).append("\" variable!"); - } - - /** - * @param myHomeRegistry | {@link ParserRegistry} provided by caller, may or may not be used... - * @param source | Source object to set the value member. - * @param member | Name/key of the member to set. - * @param val | Value to set the member to. - * @param genericVar | If true, member is expected be generic (not only string) and further parsing is required, may or may not be used... - * @param args | Some additional args to be used in case of parsing that are provided by called, may or may not be used... - * - * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link #VOID} should be returned! - * - * @since 1.3.8 - */ - @SuppressWarnings("unchecked") - public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, String member, Object val, boolean genericVar, Object... args) - { - if (source instanceof GenericScope) - { - if (val == VOID) - return ((GenericScope) source).removeVariable(member); - return ((GenericScope) source).put(genericVar ? myHomeRegistry.parse(member, true, null, args) : member, val); - } - return VOID; - } - - /** - * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * ORMATING IS NO DONE IN toString FUNCTION! - * - * @return True if variables will be serialized using json style ("key" : value)! - * - * @since 1.3.2 - */ - @Deprecated - public boolean isJsonStyle() - { - return jsonStyle; - } - - /** - * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! - * FORMATING IS NO DONE IN toString FUNCTION! - * - * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! - * - * @since 1.3.2 - */ - @Deprecated - public void setJsonStyle(boolean jsonStyle) - { - this.jsonStyle = jsonStyle; - } - - /** - * @param s | CharSequence to search! - * - * @return Index of first assignment operator ('=' or ':') if inserted expression is variable assignment expression such as variable = 4, otherwise -1! - * - * @since 1.3.0 - */ - public static int isVarAssignment(CharSequence s) - { - for (int i = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) - { - int ch = s.charAt(i); - if (ch == '"') - while (++i < len && s.charAt(i) != '"'); - else if (ch == '?') - return -1; - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && s.charAt(i) != '"'); - } - } - else if ((ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) - return i; - - oldCh = ch; - } - return -1; - } - - /** - * @param varName | Name of variable. - * @param varValue | Value of variable. - * - * @return New entry with varName as name and varValue as value! - * - * @param | Generic type of variables value. - * - * @since 1.3.5 - */ - public static Entry NewVariable(String varName, T varValue) - { - return new AbstractMap.SimpleImmutableEntry<>(varName, varValue); - } +package org.ugp.serialx.juss.converters; + +import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.Utils.splitValues; + +import java.io.IOException; +import java.util.AbstractMap; +import java.util.Map; +import java.util.Map.Entry; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.converters.DataConverter; +import org.ugp.serialx.converters.VariableParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This converter is capable of converting {@link Map.Entry} and reading variables from {@link GenericScope} by using $!
+ * {@link VariableConverter#parse} requires one additional Scope argument in args... at index 0!
+ * It manages assign operator = as well as access member operator also known as separator ".".
+ * Its case sensitive!
+ * Exact outputs of this converter are based on inserted scope! + * + * @author PETO + * + * @since 1.3.0 + * + * @see VariableParser + */ +public class VariableConverter extends VariableParser implements DataConverter +{ + @Deprecated + protected boolean jsonStyle; + + public VariableConverter() + { + this(false); + } + + /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * ORMATING IS NO DONE IN toString FUNCTION! + * + * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! + * + * @since 1.3.2 + */ + @Deprecated + public VariableConverter(boolean jsonStyle) + { + setJsonStyle(jsonStyle); + } + + /** + * Raw example of empty variable entry this converter can convert! + * + * @since 1.3.0 + */ + public static final Entry RAW_VAR_ENTRY = NewVariable("", "null"); + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String arg, Object... args) + { + if (args.length > 0 && arg.length() > 0 && args[0] instanceof GenericScope) + { + GenericScope scope = (GenericScope) args[0]; + int op0Index; + if ((op0Index = isVarAssignment(arg)) > -1) + { + boolean getValueModif = arg.charAt(0) == '$', genericVar = args.length > 4 && args[4] == GenericScope.class; + if (getValueModif) + { + arg = arg.substring(1); + op0Index--; + } + + String vars[] = splitValues(arg, op0Index, 0, 1, new char[] {'?', '<', '>', '!'}, '=', ':'), valStr; + + Object val = null; + int iVal = vars.length-1; + if (vars.length > 1 && !(valStr = vars[iVal]).isEmpty()) + { + val = myHomeRegistry.parse(valStr, args); + } + + eachVar: for (int i = 0; i < iVal; i++) // Support for assigning multiple vars to the same value... Yea this is not the prettiest code but it does the job and mainly it does it fast so shut up! + { + String var = vars[i]; + if (!genericVar) + { + if (contains(var, ' ')) + { + LogProvider.instance.logErr("Variable name \"" + var + "\" is invalid, blank characters are not allowed!", null); + continue; + } + + if ((op0Index = var.indexOf('.')) > -1) + { + String[] path = splitValues(var, op0Index, 0, 0, new char[0], '.'); + int iLast = path.length-1, j = 0; + + backlook: do + { + Object sc; + if ((sc = getMemberOperator(scope, path[0])) != VOID) // Attempt to get only when exists... + { + for (j = 1; j < iLast; j++) // Subscope/forward lookup (inner path only)... + if ((sc = getMemberOperator(sc, path[j])) == null || sc == VOID) + break backlook; + + setMemberOperator(myHomeRegistry, sc, path[iLast], val, false, args); + continue eachVar; + } + } + while ((scope = scope.getParent()) != null); + + LogProvider.instance.logErr("Path \"" + var + "\" cannot be set to \"" + val + "\" because \"" + path[j] + "\" is not a accessible or does not exist!", null); + continue; + } + } + + setMemberOperator(myHomeRegistry, scope, var, val, genericVar, args); + } + + return getValueModif ? val : VOID; + } + + return parse(myHomeRegistry, arg, scope, args); //Reading vars from scope... + } + + return CONTINUE; + } + + @Override + public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, Object... args) throws IOException + { + if (obj instanceof Entry) + { + Entry var = (Entry) obj; + + final Object key, val = var.getValue(); + if ((key = var.getKey()) instanceof String) + source.append((String) key); + else // We are likely GenericScope + myHomeRegistry.toString(source, key, args); + + if (args.length > 5 && args[5] instanceof Byte && (byte) args[5] != 0) + source.append(" = "); + else + source.append('='); + + return myHomeRegistry.toString(source, val, args); + } + return CONTINUE; + } + + @SuppressWarnings("unchecked") + @Override + public CharSequence getDescription(ParserRegistry myHomeRegistry, Object objToDescribe, Object... argsUsedConvert) + { + Entry ent = (Entry) objToDescribe; + return new StringBuilder(myHomeRegistry.getConverterFor(ent.getValue(), argsUsedConvert).getDescription(myHomeRegistry, ent.getValue(), argsUsedConvert)).append(" Stored by \"").append(ent.getKey()).append("\" variable!"); + } + + /** + * @param myHomeRegistry | {@link ParserRegistry} provided by caller, may or may not be used... + * @param source | Source object to set the value member. + * @param member | Name/key of the member to set. + * @param val | Value to set the member to. + * @param genericVar | If true, member is expected be generic (not only string) and further parsing is required, may or may not be used... + * @param args | Some additional args to be used in case of parsing that are provided by called, may or may not be used... + * + * @return By default it returns the previous value of the member. If member with provided name/key is not present in the source or its value is not possible to set, {@link #VOID} should be returned! + * + * @since 1.3.8 + */ + @SuppressWarnings("unchecked") + public Object setMemberOperator(ParserRegistry myHomeRegistry, Object source, String member, Object val, boolean genericVar, Object... args) + { + if (source instanceof GenericScope) + { + if (val == VOID) + return ((GenericScope) source).removeVariable(member); + return ((GenericScope) source).put(genericVar ? myHomeRegistry.parse(member, true, null, args) : member, val); + } + return VOID; + } + + /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * ORMATING IS NO DONE IN toString FUNCTION! + * + * @return True if variables will be serialized using json style ("key" : value)! + * + * @since 1.3.2 + */ + @Deprecated + public boolean isJsonStyle() + { + return jsonStyle; + } + + /** + * @deprecated (1.3.9) IF YOU WANT THIS TO BE TRUE, YOU WANT TO USE JsonVariableConverter FROM json-serializer MODULE! + * FORMATING IS NO DONE IN toString FUNCTION! + * + * @param jsonStyle | If true, this converter will be using Json style of variables ("key" : value)! + * + * @since 1.3.2 + */ + @Deprecated + public void setJsonStyle(boolean jsonStyle) + { + this.jsonStyle = jsonStyle; + } + + /** + * @param s | CharSequence to search! + * + * @return Index of first assignment operator ('=' or ':') if inserted expression is variable assignment expression such as variable = 4, otherwise -1! + * + * @since 1.3.0 + */ + public static int isVarAssignment(CharSequence s) + { + for (int i = 0, len = s.length(), oldCh = -1, chNext; i < len; i++) + { + int ch = s.charAt(i); + if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + else if (ch == '?') + return -1; + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + } + } + else if ((ch == '=' || ch == ':') && !(oldCh == '=' || oldCh == ':' || oldCh == '!' || oldCh == '>'|| oldCh == '<') && (i >= len-1 || !((chNext = s.charAt(i+1)) == '=' || chNext == ':' || chNext == '!' || chNext == '>'|| chNext == '<'))) + return i; + + oldCh = ch; + } + return -1; + } + + /** + * @param varName | Name of variable. + * @param varValue | Value of variable. + * + * @return New entry with varName as name and varValue as value! + * + * @param | Generic type of variables value. + * + * @since 1.3.5 + */ + public static Entry NewVariable(String varName, T varValue) + { + return new AbstractMap.SimpleImmutableEntry<>(varName, varValue); + } } \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index f5d3165..09f6ae3 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -1,215 +1,215 @@ -package org.ugp.serialx.juss.protocols; - - -import java.beans.IntrospectionException; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.Scope; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.Utils; - -/** - * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! - * This protocol is applicable on anything you want however condition of use is absence of final field otherwise {@link AutoProtocol#createBlankInstance(Class)} should be overridden. ALso you should {@link AutoProtocol#createBlankInstance(Class)} when you object is to complex! - * - * @author PETO - * - * @param | Generic type of object to use protocol for. - * - * @since 1.2.2 - */ -public class AutoProtocol extends SerializationProtocol -{ - static - { - UNIVERSAL_INTROSPECTION = Arrays.asList(); - } - - /** - * Universal instance of AutoProtocol that is applicable for any {@link Object}! - * - * @since 1.3.5 - * - * @see AutoProtocol#UNIVERSAL_SCOPE - */ - public static final AutoProtocol UNIVERSAL = new AutoProtocol<>(Object.class, AutoProtocol.UNIVERSAL_INTROSPECTION); - - /** - * Universal instance of AutoProtocol that is applicable for any {@link Object}! - * Object will be serialized as {@link Scope}! - * - * @since 1.3.5 - */ - public static final AutoProtocol UNIVERSAL_SCOPE = new AutoProtocol<>(Object.class, true, AutoProtocol.UNIVERSAL_INTROSPECTION); - - /** - * This is information for {@link AutoProtocol} to always introspect structure of every object before that is being serialized or deserialized, which means all fields with public and valid getters and setters will be serialized for every object! - *
- * This is default behavior of {@link AutoProtocol} when no fields are specified in constructor! - * - * @since 1.3.5 - */ - public static final List UNIVERSAL_INTROSPECTION; - - protected final Class applicableFor; - protected List fieldDescriptors; - protected HashMap, List> cache = new HashMap<>(); - protected boolean useScope; - - /** - * @param applicableFor | Class that can be serialized using this protocol. - * @param fieldsToSerialize | Names of fields to serialize, if empty array is put there then all fields with public and valid getters and setters will be serialized! - * - * @throws IntrospectionException when there are no field with valid and public getters and setters. - * - * @since 1.2.2 - */ - public AutoProtocol(Class applicableFor, String... fieldsToSerialize) throws IntrospectionException - { - this(applicableFor, false, fieldsToSerialize); - } - - /** - * @param applicableFor | Class that can be serialized using this protocol. - * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null all fields width valid and public getters and setters will be serialized! - * - * @since 1.3.5 - */ - public AutoProtocol(Class applicableFor, List fieldsToSerialize) - { - this(applicableFor, false, fieldsToSerialize); - } - - /** - * @param applicableFor | Class that can be serialized using this protocol. - * @param useScope | If true, objects will be serialized using scope which is longer but more readable! - * @param fieldsToSerialize | Names of fields to serialize, if this array is empty or null then all fields with public and valid getters and setters will be serialized! - * - * @throws IntrospectionException when there are no fields with valid and public getters and setters. - * - * @since 1.3.2 - */ - public AutoProtocol(Class applicableFor, boolean useScope, String... fieldsToSerialize) throws IntrospectionException - { - this(applicableFor, useScope, fieldsToSerialize == null || fieldsToSerialize.length == 0 ? UNIVERSAL_INTROSPECTION : Scope.getPropertyDescriptorsOf(applicableFor, fieldsToSerialize)); - } - - /** - * @param applicableFor | Class that can be serialized using this protocol. - * @param useScope | If true, objects will be serialized using scope which is longer but more readable! - * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null {@link AutoProtocol#UNIVERSAL_INTROSPECTION} will take place! - * - * @since 1.3.5 - */ - public AutoProtocol(Class applicableFor, boolean useScope, List fieldsToSerialize) - { - this.applicableFor = applicableFor; - setUseScope(useScope); - this.fieldDescriptors = fieldsToSerialize == null ? UNIVERSAL_INTROSPECTION : fieldsToSerialize; - - if (fieldDescriptors == UNIVERSAL_INTROSPECTION) - try - { - Scope.getPropertyDescriptorsOf(applicableFor, cache); - } - catch (IntrospectionException e) - {} - } - - /** - * @param objectClass | Class to create new instance of! - * - * @return New blank instance of required class! When not override, it returns {@link Utils#Instantiate(Class)} - * - * @throws Exception if any exception occurs (based on implementation). - * - * @since 1.2.2 - */ - public T createBlankInstance(Class objectClass) throws Exception - { - return Utils.Instantiate(objectClass); - } - - @Override - public Object[] serialize(T object) throws Exception - { - List fieldDescriptors = getFieldDescriptors(); - if (fieldDescriptors == UNIVERSAL_INTROSPECTION) - fieldDescriptors = Scope.getPropertyDescriptorsOf(object.getClass(), cache); - - if (isUseScope()) - return new Object[] {Scope.from(object, fieldDescriptors)}; - - int size = fieldDescriptors.size(); - Object[] args = new Object[size]; - for (int i = 0; i < size; i++) - args[i] = fieldDescriptors.get(i).getReadMethod().invoke(object); - return args; - } - - @SuppressWarnings("unchecked") - @Override - public T unserialize(Class objectClass, Object... args) throws Exception - { - List fieldDescriptors = getFieldDescriptors(); - if (fieldDescriptors == UNIVERSAL_INTROSPECTION) - fieldDescriptors = Scope.getPropertyDescriptorsOf(objectClass, cache); - - T obj = createBlankInstance(objectClass); - if (isUseScope() && args.length == 1 && args[0] instanceof Scope) - { - return Scope.into(obj, (Scope) args[0], fieldDescriptors); - } - - for (int i = 0, size = Math.min(fieldDescriptors.size(), args.length); i < size; i++) - { - Method setter = fieldDescriptors.get(i).getWriteMethod(); - Type expectedType = setter.getGenericParameterTypes()[0]; - setter.invoke(obj, args[i] instanceof GenericScope && expectedType != args[i].getClass() ? ((GenericScope) args[i]).toObject(expectedType) : args[i]); - } - return obj; - } - - /** - * @return PropertyDescriptors of variables that are used by this protocol!
- * Note: I would recommend to tread this as read only and not modify anything that you are not sure of. This will ensure correct functionality of this protocol... - * - * @since 1.3.2 - */ - public List getFieldDescriptors() - { - return this.fieldDescriptors; - } - - @Override - public Class applicableFor() - { - return applicableFor; - } - - /** - * @return If true, objects will be serialized using scope which is longer but more readable! - * - * @since 1.3.2 - */ - public boolean isUseScope() - { - return useScope; - } - - /** - * @param useScope | If true, objects will be serialized using scope which is longer but more readable! - * - * @since 1.3.2 - */ - public void setUseScope(boolean useScope) - { - this.useScope = useScope; - } -} +package org.ugp.serialx.juss.protocols; + + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.Scope; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.Utils; + +/** + * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! + * This protocol is applicable on anything you want however condition of use is absence of final field otherwise {@link AutoProtocol#createBlankInstance(Class)} should be overridden. ALso you should {@link AutoProtocol#createBlankInstance(Class)} when you object is to complex! + * + * @author PETO + * + * @param | Generic type of object to use protocol for. + * + * @since 1.2.2 + */ +public class AutoProtocol extends SerializationProtocol +{ + static + { + UNIVERSAL_INTROSPECTION = Arrays.asList(); + } + + /** + * Universal instance of AutoProtocol that is applicable for any {@link Object}! + * + * @since 1.3.5 + * + * @see AutoProtocol#UNIVERSAL_SCOPE + */ + public static final AutoProtocol UNIVERSAL = new AutoProtocol<>(Object.class, AutoProtocol.UNIVERSAL_INTROSPECTION); + + /** + * Universal instance of AutoProtocol that is applicable for any {@link Object}! + * Object will be serialized as {@link Scope}! + * + * @since 1.3.5 + */ + public static final AutoProtocol UNIVERSAL_SCOPE = new AutoProtocol<>(Object.class, true, AutoProtocol.UNIVERSAL_INTROSPECTION); + + /** + * This is information for {@link AutoProtocol} to always introspect structure of every object before that is being serialized or deserialized, which means all fields with public and valid getters and setters will be serialized for every object! + *
+ * This is default behavior of {@link AutoProtocol} when no fields are specified in constructor! + * + * @since 1.3.5 + */ + public static final List UNIVERSAL_INTROSPECTION; + + protected final Class applicableFor; + protected List fieldDescriptors; + protected HashMap, List> cache = new HashMap<>(); + protected boolean useScope; + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param fieldsToSerialize | Names of fields to serialize, if empty array is put there then all fields with public and valid getters and setters will be serialized! + * + * @throws IntrospectionException when there are no field with valid and public getters and setters. + * + * @since 1.2.2 + */ + public AutoProtocol(Class applicableFor, String... fieldsToSerialize) throws IntrospectionException + { + this(applicableFor, false, fieldsToSerialize); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null all fields width valid and public getters and setters will be serialized! + * + * @since 1.3.5 + */ + public AutoProtocol(Class applicableFor, List fieldsToSerialize) + { + this(applicableFor, false, fieldsToSerialize); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * @param fieldsToSerialize | Names of fields to serialize, if this array is empty or null then all fields with public and valid getters and setters will be serialized! + * + * @throws IntrospectionException when there are no fields with valid and public getters and setters. + * + * @since 1.3.2 + */ + public AutoProtocol(Class applicableFor, boolean useScope, String... fieldsToSerialize) throws IntrospectionException + { + this(applicableFor, useScope, fieldsToSerialize == null || fieldsToSerialize.length == 0 ? UNIVERSAL_INTROSPECTION : Scope.getPropertyDescriptorsOf(applicableFor, fieldsToSerialize)); + } + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * @param fieldsToSerialize | PropertyDescriptor of fields to serialize, if null {@link AutoProtocol#UNIVERSAL_INTROSPECTION} will take place! + * + * @since 1.3.5 + */ + public AutoProtocol(Class applicableFor, boolean useScope, List fieldsToSerialize) + { + this.applicableFor = applicableFor; + setUseScope(useScope); + this.fieldDescriptors = fieldsToSerialize == null ? UNIVERSAL_INTROSPECTION : fieldsToSerialize; + + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + try + { + Scope.getPropertyDescriptorsOf(applicableFor, cache); + } + catch (IntrospectionException e) + {} + } + + /** + * @param objectClass | Class to create new instance of! + * + * @return New blank instance of required class! When not override, it returns {@link Utils#Instantiate(Class)} + * + * @throws Exception if any exception occurs (based on implementation). + * + * @since 1.2.2 + */ + public T createBlankInstance(Class objectClass) throws Exception + { + return Utils.Instantiate(objectClass); + } + + @Override + public Object[] serialize(T object) throws Exception + { + List fieldDescriptors = getFieldDescriptors(); + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + fieldDescriptors = Scope.getPropertyDescriptorsOf(object.getClass(), cache); + + if (isUseScope()) + return new Object[] {Scope.from(object, fieldDescriptors)}; + + int size = fieldDescriptors.size(); + Object[] args = new Object[size]; + for (int i = 0; i < size; i++) + args[i] = fieldDescriptors.get(i).getReadMethod().invoke(object); + return args; + } + + @SuppressWarnings("unchecked") + @Override + public T unserialize(Class objectClass, Object... args) throws Exception + { + List fieldDescriptors = getFieldDescriptors(); + if (fieldDescriptors == UNIVERSAL_INTROSPECTION) + fieldDescriptors = Scope.getPropertyDescriptorsOf(objectClass, cache); + + T obj = createBlankInstance(objectClass); + if (isUseScope() && args.length == 1 && args[0] instanceof Scope) + { + return Scope.into(obj, (Scope) args[0], fieldDescriptors); + } + + for (int i = 0, size = Math.min(fieldDescriptors.size(), args.length); i < size; i++) + { + Method setter = fieldDescriptors.get(i).getWriteMethod(); + Type expectedType = setter.getGenericParameterTypes()[0]; + setter.invoke(obj, args[i] instanceof GenericScope && expectedType != args[i].getClass() ? ((GenericScope) args[i]).toObject(expectedType) : args[i]); + } + return obj; + } + + /** + * @return PropertyDescriptors of variables that are used by this protocol!
+ * Note: I would recommend to tread this as read only and not modify anything that you are not sure of. This will ensure correct functionality of this protocol... + * + * @since 1.3.2 + */ + public List getFieldDescriptors() + { + return this.fieldDescriptors; + } + + @Override + public Class applicableFor() + { + return applicableFor; + } + + /** + * @return If true, objects will be serialized using scope which is longer but more readable! + * + * @since 1.3.2 + */ + public boolean isUseScope() + { + return useScope; + } + + /** + * @param useScope | If true, objects will be serialized using scope which is longer but more readable! + * + * @since 1.3.2 + */ + public void setUseScope(boolean useScope) + { + this.useScope = useScope; + } +} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java index 1619025..7d299eb 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializable.java @@ -1,20 +1,20 @@ -package org.ugp.serialx.juss.protocols; - -/** - * This is based on pretty similar concept as regular {@link java.io.Serializable} is! However this interface is meant to create its instance programmatically via constructor! - * So condition of using this is that array of objects returned by {@link SelfSerializable#serialize()} must be applicable for some public constructor of certain class implementing this! - * Specific instances of this interface will be created by calling that public constructor! This is done reflectively by {@link SelfSerializableProtocol}! - * - * @author PETO - * - * @since 1.2.2 - */ -public interface SelfSerializable -{ - /** - * @return Array of objects that can be applied to certain public constructor of this class! This constructor will be then used as unserialize method and will be called during unserialization! - * - * @since 1.2.2 - */ - public Object[] serialize(); -} +package org.ugp.serialx.juss.protocols; + +/** + * This is based on pretty similar concept as regular {@link java.io.Serializable} is! However this interface is meant to create its instance programmatically via constructor! + * So condition of using this is that array of objects returned by {@link SelfSerializable#serialize()} must be applicable for some public constructor of certain class implementing this! + * Specific instances of this interface will be created by calling that public constructor! This is done reflectively by {@link SelfSerializableProtocol}! + * + * @author PETO + * + * @since 1.2.2 + */ +public interface SelfSerializable +{ + /** + * @return Array of objects that can be applied to certain public constructor of this class! This constructor will be then used as unserialize method and will be called during unserialization! + * + * @since 1.2.2 + */ + public Object[] serialize(); +} diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java index e1d3495..fc26024 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/SelfSerializableProtocol.java @@ -1,39 +1,39 @@ -package org.ugp.serialx.juss.protocols; - -/** - * SelfSerializableProtocol is universal protocol to serialize any {@link SelfSerializable} instance. The condition of use is implementation of {@link SelfSerializable} interface and public constructor that can be called with content returned by specific {@link SelfSerializable#serialize()}! - * - * @param Type of SelfSerializable class that this protocol should be applicable for... - * - * @author PETO - * - * @since 1.2.2 - * - * @see UniversalObjectInstantiationProtocol - */ -public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol -{ - /** - * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
- * Note: Passing {@link SelfSerializable}.class will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered a security risk in some cases... - * - * @since 1.3.8 - */ - public SelfSerializableProtocol(Class applicableFor) - { - super(applicableFor); - } - - @Override - public Object[] serialize(T object) - { - return object.serialize(); - } - - @Override - public long getMode() - { - return MODE_SERIALIZE_DESERIALIZE; - } -} +package org.ugp.serialx.juss.protocols; + +/** + * SelfSerializableProtocol is universal protocol to serialize any {@link SelfSerializable} instance. The condition of use is implementation of {@link SelfSerializable} interface and public constructor that can be called with content returned by specific {@link SelfSerializable#serialize()}! + * + * @param Type of SelfSerializable class that this protocol should be applicable for... + * + * @author PETO + * + * @since 1.2.2 + * + * @see UniversalObjectInstantiationProtocol + */ +public class SelfSerializableProtocol extends UniversalObjectInstantiationProtocol +{ + /** + * @param applicableFor | Class implementing {@link SelfSerializable} that can be serialized using this protocol.
+ * Note: Passing {@link SelfSerializable}.class will make this protocol universal and work for any {@link SelfSerializable} instance, this can be considered a security risk in some cases... + * + * @since 1.3.8 + */ + public SelfSerializableProtocol(Class applicableFor) + { + super(applicableFor); + } + + @Override + public Object[] serialize(T object) + { + return object.serialize(); + } + + @Override + public long getMode() + { + return MODE_SERIALIZE_DESERIALIZE; + } +} \ No newline at end of file diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index 6c6fd69..bd81085 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -1,99 +1,99 @@ -package org.ugp.serialx.juss.protocols; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Type; -import java.util.Arrays; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; - -/** - * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! - * Note: This protocol is for deserialization only! - * - * @author PETO - * - * @param Generic type of deserialized object! - * - * @since 1.3.5 - */ -public class UniversalObjectInstantiationProtocol extends SerializationProtocol { - - protected final Class applicableFor; - - /** - * @param applicableFor | Class that can be serialized using this protocol. - * Note: Passing {@link Object#getClass()} will make this protocol universal and work for any {@link Object} instance, this can be considered unsafe in some cases... - * - * @since 1.3.8 - */ - public UniversalObjectInstantiationProtocol(Class applicableFor) - { - this.applicableFor = applicableFor; - } - - @Override - public Object[] serialize(T object) - { - throw new UnsupportedOperationException("This protocol is only for reading! It cant serialize " + object); - } - - @SuppressWarnings("unchecked") - @Override - public T unserialize(Class objectClass, Object... args) throws Exception - { - try - { - return objectClass.getConstructor(Utils.ToClasses(args)).newInstance(args); - } - catch (Exception e0) - { - int argCount = args.length; - for (Constructor cons : objectClass.getConstructors()) - if (cons.getParameterCount() == argCount) - try - { - return (T) cons.newInstance(args); - } - catch (IllegalArgumentException e) - { - try - { - for (int i = 0; i < argCount; i++) - { - Object arg; - if ((arg = args[i]) instanceof GenericScope) - { - Type[] paramTypes; - args = args.clone(); - args[i] = ((GenericScope) arg).toObject((paramTypes = cons.getGenericParameterTypes())[i]); - - for (i++; i < argCount; i++) - if ((arg = args[i]) instanceof GenericScope) - args[i] = ((GenericScope) arg).toObject(paramTypes[i]); - return (T) cons.newInstance(args); - } - } - } - catch (IllegalArgumentException e2) - {} - } - } - LogProvider.instance.logErr("Unable to create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); - return null; - } - - @Override - public Class applicableFor() - { - return applicableFor; - } - - @Override - public long getMode() - { - return MODE_DESERIALIZE; - } -} +package org.ugp.serialx.juss.protocols; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Type; +import java.util.Arrays; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.protocols.SerializationProtocol; +import org.ugp.serialx.utils.LogProvider; +import org.ugp.serialx.utils.Utils; + +/** + * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! + * Note: This protocol is for deserialization only! + * + * @author PETO + * + * @param Generic type of deserialized object! + * + * @since 1.3.5 + */ +public class UniversalObjectInstantiationProtocol extends SerializationProtocol { + + protected final Class applicableFor; + + /** + * @param applicableFor | Class that can be serialized using this protocol. + * Note: Passing {@link Object#getClass()} will make this protocol universal and work for any {@link Object} instance, this can be considered unsafe in some cases... + * + * @since 1.3.8 + */ + public UniversalObjectInstantiationProtocol(Class applicableFor) + { + this.applicableFor = applicableFor; + } + + @Override + public Object[] serialize(T object) + { + throw new UnsupportedOperationException("This protocol is only for reading! It cant serialize " + object); + } + + @SuppressWarnings("unchecked") + @Override + public T unserialize(Class objectClass, Object... args) throws Exception + { + try + { + return objectClass.getConstructor(Utils.ToClasses(args)).newInstance(args); + } + catch (Exception e0) + { + int argCount = args.length; + for (Constructor cons : objectClass.getConstructors()) + if (cons.getParameterCount() == argCount) + try + { + return (T) cons.newInstance(args); + } + catch (IllegalArgumentException e) + { + try + { + for (int i = 0; i < argCount; i++) + { + Object arg; + if ((arg = args[i]) instanceof GenericScope) + { + Type[] paramTypes; + args = args.clone(); + args[i] = ((GenericScope) arg).toObject((paramTypes = cons.getGenericParameterTypes())[i]); + + for (i++; i < argCount; i++) + if ((arg = args[i]) instanceof GenericScope) + args[i] = ((GenericScope) arg).toObject(paramTypes[i]); + return (T) cons.newInstance(args); + } + } + } + catch (IllegalArgumentException e2) + {} + } + } + LogProvider.instance.logErr("Unable to create new instance of \"" + objectClass + "\" because inserted arguments " + Arrays.asList(args) + " cannot be applied on any public constructor in required class!", null); + return null; + } + + @Override + public Class applicableFor() + { + return applicableFor; + } + + @Override + public long getMode() + { + return MODE_DESERIALIZE; + } +} diff --git a/SerialX-operators/pom.xml b/SerialX-operators/pom.xml index 9152893..f651447 100644 --- a/SerialX-operators/pom.xml +++ b/SerialX-operators/pom.xml @@ -1,25 +1,25 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - - - org.ugp.serialx - serialx-operators - 4.0.0-SNAPSHOT - - SerialX operators - This modul contains basic operators contained in almost every programing language... - - - - org.ugp.serialx - serialx-core - 4.0.0-SNAPSHOT - - + + 4.0.0 + + org.ugp + serialx + ${revision} + + + org.ugp.serialx + serialx-operators + 4.0.0-SNAPSHOT + + SerialX operators + This modul contains basic operators contained in almost every programing language... + + + + org.ugp.serialx + serialx-core + 4.0.0-SNAPSHOT + + \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java index e0aa691..2a4c116 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/Operators.java @@ -1,69 +1,69 @@ -package org.ugp.serialx.converters; - -import java.util.Arrays; - -import org.ugp.serialx.converters.DataParser.ParserRegistry; -import org.ugp.serialx.converters.operators.ArithmeticOperators; -import org.ugp.serialx.converters.operators.ComparisonOperators; -import org.ugp.serialx.converters.operators.ConditionalAssignmentOperators; -import org.ugp.serialx.converters.operators.LogicalOperators; -import org.ugp.serialx.converters.operators.NegationOperator; - -/** - * This class contains all operators that are provided by this module and it allows you to install it to your specific {@link ParserRegistry}! - * - * @see Operators#install(ParserRegistry) - * - * @since 1.3.8 - * - * @author PETO - */ -public class Operators { - - /** - * Array that contains all binary operators (operators that require 2 operands, one from left, one from right). This includes:
- * {@link ConditionalAssignmentOperators}
- * {@link LogicalOperators}
- * {@link ComparisonOperators}
- * {@link ArithmeticOperators}
- * In given order! - * - * @since 1.3.8 - */ - public static final DataParser[] BINARY = { new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators() }; - - /** - * Array that contains all unary operators (operators that require only 1 operands, from left or right). This includes:
- * {@link NegationOperator}
- * In given order! - * - * @since 1.3.8 - */ - public static final DataParser[] UNARY = { new NegationOperator() }; - - /** - * @param registry | Registry to insert all operators provided by {@link Operators#BINARY} and {@link Operators#UNARY} into. This register is required to contains {@link StringConverter} and {@link BooleanConverter} in order for operators to be inserted in correct order and work in precedence they were meant to. - * - * @return The same registry with operators inserted! - * - * @since 1.3.8 - */ - public static ParserRegistry install(ParserRegistry registry) { - registry.addAllBefore(StringConverter.class, true, BINARY); - registry.addAllBefore(BooleanConverter.class, true, UNARY); - return registry; - } - - /** - * @param registry | Registry to remove all operators from! - * - * @return The same registry with no more operators! - * - * @since 1.3.8 - */ - public static ParserRegistry uninstall(ParserRegistry registry) { - registry.removeAll(Arrays.asList(BINARY)); - registry.removeAll(Arrays.asList(UNARY)); - return registry; - } -} +package org.ugp.serialx.converters; + +import java.util.Arrays; + +import org.ugp.serialx.converters.DataParser.ParserRegistry; +import org.ugp.serialx.converters.operators.ArithmeticOperators; +import org.ugp.serialx.converters.operators.ComparisonOperators; +import org.ugp.serialx.converters.operators.ConditionalAssignmentOperators; +import org.ugp.serialx.converters.operators.LogicalOperators; +import org.ugp.serialx.converters.operators.NegationOperator; + +/** + * This class contains all operators that are provided by this module and it allows you to install it to your specific {@link ParserRegistry}! + * + * @see Operators#install(ParserRegistry) + * + * @since 1.3.8 + * + * @author PETO + */ +public class Operators { + + /** + * Array that contains all binary operators (operators that require 2 operands, one from left, one from right). This includes:
+ * {@link ConditionalAssignmentOperators}
+ * {@link LogicalOperators}
+ * {@link ComparisonOperators}
+ * {@link ArithmeticOperators}
+ * In given order! + * + * @since 1.3.8 + */ + public static final DataParser[] BINARY = { new ConditionalAssignmentOperators(), new LogicalOperators(), new ComparisonOperators(), new ArithmeticOperators() }; + + /** + * Array that contains all unary operators (operators that require only 1 operands, from left or right). This includes:
+ * {@link NegationOperator}
+ * In given order! + * + * @since 1.3.8 + */ + public static final DataParser[] UNARY = { new NegationOperator() }; + + /** + * @param registry | Registry to insert all operators provided by {@link Operators#BINARY} and {@link Operators#UNARY} into. This register is required to contains {@link StringConverter} and {@link BooleanConverter} in order for operators to be inserted in correct order and work in precedence they were meant to. + * + * @return The same registry with operators inserted! + * + * @since 1.3.8 + */ + public static ParserRegistry install(ParserRegistry registry) { + registry.addAllBefore(StringConverter.class, true, BINARY); + registry.addAllBefore(BooleanConverter.class, true, UNARY); + return registry; + } + + /** + * @param registry | Registry to remove all operators from! + * + * @return The same registry with no more operators! + * + * @since 1.3.8 + */ + public static ParserRegistry uninstall(ParserRegistry registry) { + registry.removeAll(Arrays.asList(BINARY)); + registry.removeAll(Arrays.asList(UNARY)); + return registry; + } +} diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 19012c1..63ad024 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -1,511 +1,511 @@ -package org.ugp.serialx.converters.operators; - -import static java.util.Arrays.asList; -import static org.ugp.serialx.utils.Utils.*; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.ListIterator; - -import org.ugp.serialx.GenericScope; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides arithmetics operators to evaluate mathematical expressions such as 5 * 2 +-- 2 / 2 ** 2 % 4 = 10! - * - * @author PETO - * - * @since 1.3.0 - */ -public class ArithmeticOperators implements DataParser -{ - /** - * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator}.
Intended for override, should not be null or empty! - * - * @since 1.3.8 - */ - protected char[] operators = {'+', '-', '*', '/', '%'}; - - @SuppressWarnings("unchecked") - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len; - if ((len = str.length()) > 2 && isExpression(str, len, operators)) - { - for (int i = 0; i < len; ) // Format duplicates of [+-]{2} - if (isOneOf(str.charAt(i++), '+', '-') && i < len && isOneOf(str.charAt(i), '+', '-')) - { - len = (str = fastReplace(fastReplace(fastReplace(fastReplace(str, "-+", "-"), "+-", "-"), "--", "+"), "++", "+")).length(); - i--; - } - - List[] terms = getAndParseTerms(str, len, myHomeRegistry, args, getClass(), operators); - ArrayList cofs = (ArrayList) terms[0]; - if (cofs.size() <= 1) - return cofs.get(0); - LinkedList oprs = (LinkedList) terms[1]; - - String op = null; - int index = 1; - try - { - for (int opPrio = getHighestPriority(); opPrio > 0; opPrio--) - for (ListIterator iter = oprs.listIterator(); iter.hasNext(); ) - { - if (getOperatorPriority(op = iter.next()) == opPrio) - { - iter.remove(); - cofs.set(index = iter.nextIndex(), operator(cofs.get(index), op, cofs.remove(index + 1), myHomeRegistry, args)); - } - } - - for (index = 1; (op = oprs.poll()) != null; ) - cofs.set(0, operator(cofs.get(0), op, cofs.get(index++), myHomeRegistry, args)); - } - catch (ClassCastException ex) - { - LogProvider.instance.logErr("Arithmetic operator " + op + " is undefined between provided operands because " + ex.getMessage() + "!", ex); - } - catch (IndexOutOfBoundsException ex) - { - LogProvider.instance.logErr("Missing operand in \"" + str + "\"!", null); - } - catch (ArithmeticException ex) - { - LogProvider.instance.logErr(ex.getMessage(), ex); - } - - return cofs.get(0); - } - return CONTINUE; - } - - /** - * @param opr1 | Operand 1 - * @param op | The operator/operation - * @param opr2 | Operand 2 - * @param myHomeRegistry | Registry provided by the caller, use only in special cases! - * @param args | Some additional args provided by the caller for the myHomeRegistry, use only in special cases! - * - * @return Result of binary operation described by op between opr1 and opr2! If operator is not known, opr1 will be returned by default! - * - * @since 1.3.8 - */ - public Object operator(Object opr1, String op, Object opr2, ParserRegistry myHomeRegistry, Object... args) - { -// System.err.println(opr1 + op + opr2); - switch (op.charAt(0)) - { - case '+': - return addOperator(opr1, opr2); - case '-': - return subOperator(opr1, opr2); - case '*': - if (op.length() > 1 && op.charAt(1) == '*') - return powOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); - return multOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); - case '/': - return divOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); - case '%': - return modOperator(opr1, opr2); - } - return opr1; - } - - /** - * @param op | The operator/operation - * - * @return Priority of provided operator (higher number = higher priority, 2 = high, 1 = medium, 0 = low) - * - * @see ArithmeticOperators#getHighestPriority() - * - * @since 1.3.8 - */ - public byte getOperatorPriority(String op) - { - switch (op.charAt(0)) - { - case '+': - case '-': - return 0; // Low - case '*': - if (op.length() > 1 && op.charAt(1) == '*') - return 2; // High ** - default: - return 1; // Medium * / % - } - } - - /** - * @return Number representing highest possible priority of operator (default is 2). - * - * @since 1.3.9 - */ - protected byte getHighestPriority() - { - return 2; - } - - /** - * @return Addition of cof and cof2 (cof + cof2) supposed to be returned! - * - * @since 1.3.2 - */ - public Object addOperator(Object cof, Object cof2) - { - return add(toNum(cof), cof instanceof String ? cof2 : toNum(cof2)); - } - - /** - * @return Subtraction of cof and cof2 (cof - cof2) supposed to be returned! - * - * @since 1.3.2 - */ - public Object subOperator(Object cof, Object cof2) - { - return sub(toNum(cof), toNum(cof2)); - } - - /** - * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign) supposed to be returned! - * - * @since 1.3.2 - */ - public Object multOperator(Object cof, Object cof2, int sign) - { - return mult(toNum(cof), toNum(cof2), sign); - } - - /** - * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign) supposed to be returned! - * - * @since 1.3.2 - */ - public Object divOperator(Object cof, Object cof2, int sign) - { - return div(toNum(cof), toNum(cof2), sign); - } - - /** - * @return Modulation of cod and cof2 (cof % cof2) supposed to be returned! - * - * @since 1.3.2 - */ - public Object modOperator(Object cof, Object cof2) - { - return mod(toNum(cof), toNum(cof2)); - } - - /** - * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign)) supposed to be returned! - * - * @since 1.3.2 - */ - public Object powOperator(Object cof, Object cof2, int sign) - { - return pow(toNum(cof), toNum(cof2), sign); - } - - /** - * @return Addition of cof and cof2 (cof + cof2)! - * - * @since 1.3.0 - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Object add(Object cof, Object cof2) - { - if (cof instanceof Number && cof2 instanceof Number) - { - if (cof instanceof Double || cof2 instanceof Double) - return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); - if (cof instanceof Float || cof2 instanceof Float) - return ((Number) cof).floatValue() + ((Number) cof2).floatValue(); - if (cof instanceof Integer || cof2 instanceof Integer) - return ((Number) cof).intValue() + ((Number) cof2).intValue(); - if (cof instanceof Long || cof2 instanceof Long) - return ((Number) cof).longValue() + ((Number) cof2).longValue(); - - return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); - } - - if (cof.getClass().isArray()) - return mergeArrays(cof, cof2); - - if (cof instanceof Collection) - { - if (cof2 instanceof Collection) - ((Collection) cof).addAll(((Collection) cof2)); - else if (cof2.getClass().isArray()) - ((Collection) cof).addAll(asList(fromAmbiguousArray(cof2))); - else - ((Collection) cof).add(cof2); - return cof; - } - - if (cof instanceof GenericScope) - { - if (cof2 instanceof GenericScope) - ((GenericScope) cof).addAll(((GenericScope) cof2)); - else if (cof2 instanceof Collection) - ((GenericScope) cof).addAll((Collection) cof2); - else if (cof2.getClass().isArray()) - ((GenericScope) cof).addAll(fromAmbiguousArray(cof2)); - else - ((GenericScope) cof).add(cof2); - return cof; - } - return String.valueOf(cof) + String.valueOf(cof2); - } - - /** - * @return Subtraction of cof and cof2 (cof - cof2)! - * - * @since 1.3.0 - */ - @SuppressWarnings({ "unchecked", "rawtypes" }) - public static Object sub(Object cof, Object cof2) - { - if (cof instanceof Number && cof2 instanceof Number) - { - if (cof instanceof Double || cof2 instanceof Double) - return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); - if (cof instanceof Float || cof2 instanceof Float) - return ((Number) cof).floatValue() - ((Number) cof2).floatValue(); - if (cof instanceof Integer || cof2 instanceof Integer) - return ((Number) cof).intValue() - ((Number) cof2).intValue(); - if (cof instanceof Long || cof2 instanceof Long) - return ((Number) cof).longValue() - ((Number) cof2).longValue(); - - return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); - } - - if (cof instanceof Collection) - { - if (cof2 instanceof Collection) - ((Collection) cof).removeAll(((Collection) cof2)); - else if (cof2.getClass().isArray()) - ((Collection) cof).removeAll(asList(fromAmbiguousArray(cof2))); - else - ((Collection) cof).remove(cof2); - return cof; - } - - if (cof instanceof GenericScope) - { - if (cof2 instanceof Collection) - ((GenericScope) cof).values().removeAll((Collection) cof2); - else if (cof2.getClass().isArray()) - ((GenericScope) cof).values().removeAll(asList(cof2)); - else - ((GenericScope) cof).values().remove(cof2); - return cof; - } - - return null; - } - - /** - * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign)! - * - * @since 1.3.0 - */ - public static Object mult(Object cof, Object cof2, int sign) - { - if (cof2 instanceof Number) - { - if (!(cof instanceof Number)) - return multilpy(cof.toString(), ((Number) cof2).intValue() * sign).toString(); - - if (cof instanceof Double || cof2 instanceof Double) - return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; - if (cof instanceof Float || cof2 instanceof Float) - return ((Number) cof).floatValue() * ((Number) cof2).floatValue() * sign; - if (cof instanceof Integer || cof2 instanceof Integer) - return ((Number) cof).intValue() * ((Number) cof2).intValue() * sign; - if (cof instanceof Long || cof2 instanceof Long) - return ((Number) cof).longValue() * ((Number) cof2).longValue() * sign; - - return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; - } - - return multilpy(cof2.toString(), ((Number) cof).intValue() * sign).toString(); - } - - /** - * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign)! - * - * @since 1.3.0 - */ - public static Object div(Object cof, Object cof2, int sign) - { - if (cof instanceof Double || cof2 instanceof Double) - return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; - if (cof instanceof Float || cof2 instanceof Float) - return ((Number) cof).floatValue() / ((Number) cof2).floatValue() * sign; - if (cof instanceof Integer || cof2 instanceof Integer) - return ((Number) cof).intValue() / ((Number) cof2).intValue() * sign; - if (cof instanceof Long || cof2 instanceof Long) - return ((Number) cof).longValue() / ((Number) cof2).longValue() * sign; - - return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; - } - - /** - * @return Modulation of cod and cof2 (cof % cof2)! - * - * @since 1.3.0 - */ - public static Object mod(Object cof, Object cof2) - { - if (cof instanceof Double || cof2 instanceof Double) - return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); - if (cof instanceof Float || cof2 instanceof Float) - return ((Number) cof).floatValue() % ((Number) cof2).floatValue(); - if (cof instanceof Integer || cof2 instanceof Integer) - return ((Number) cof).intValue() % ((Number) cof2).intValue(); - if (cof instanceof Long || cof2 instanceof Long) - return ((Number) cof).longValue() % ((Number) cof2).longValue(); - - return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); - } - - /** - * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign))! - * - * @since 1.3.0 - */ - public static Object pow(Object cof, Object cof2, int sign) - { - double pow = Math.pow(((Number) cof).doubleValue(), ((Number) cof2).doubleValue() * sign); - if (pow > Long.MAX_VALUE || pow < Long.MIN_VALUE || cof instanceof Double || cof2 instanceof Double) - return pow; - if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Float || cof2 instanceof Float)) - return (float) pow; - - if (pow > Integer.MAX_VALUE || pow < Integer.MIN_VALUE || cof instanceof Long || cof2 instanceof Long) - return (long) pow; - if (cof instanceof Integer || cof2 instanceof Integer) - return (int) pow; - return pow; - } - - /** - * @param str | String to split! - * @param to | Ending index of parsing, exclusive. Everything from this index to the end will be ignored (should be str.length())! - * @param registryForParsers | Registry to use for parsing operands! - * @param argsForParsers | Arguments for the parse method! - * @param classToIgnore | Parser to ignore (should be class of the caller if possible)! - * @param oprs | Operators to use as a splitters. 1 or more of these in row will be used as delimiter! - * - * @return Array with 2 lists. Index 0 is {@link ArrayList} containing parsed operands of the expression, index 1 is {@link LinkedList} containing operators of the expression! - * - * @since 1.3.8 (originally getTerms since 1.3.0) - */ - @SuppressWarnings("unchecked") - public static List[] getAndParseTerms(String str, int to, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs) - { - List[] ret = new List[] {new ArrayList(), new LinkedList()}; //cofs, ops - - int i = 0, startIndex = 0, type = 0; - for (; i < to && isOneOf(str.charAt(i), oprs); i++); //in case of start cof sign - - for (int quote = 0, brackets = 0, lastType = type; i < to; i++) - { - char ch = str.charAt(i); - if (ch == '\"') - quote++; - else if ((ch | ' ') == '{') - brackets++; - else if ((ch | ' ') == '}') - brackets--; - else if (type == 1 || quote % 2 == 0 && brackets == 0) - { - if ((type = isOneOf(ch, oprs) ? 1 : 0) != lastType) - { - String s = str.substring(startIndex, i).trim(); - if (!s.isEmpty()) - ret[lastType].add(lastType == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); - startIndex = i; - } - else - type = lastType; - } - - lastType = type; - } - - String s = str.substring(startIndex, to).trim(); - if (!s.isEmpty()) - ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); -// System.err.println(ret[0] + "\n" + ret[1] + "\n"); - return ret; - } - - /** - * @param str | String that might be an expression! - * @param to | Ending index of checking, exclusive (should be str.length())! - * @param operators | Operators that str must have! - * - * @return True if inserted string is expression with any coefficients splitted by operators! - * - * @since 1.3.2 - */ - public static boolean isExpression(CharSequence str, int to, char... operators) - { - int hasOpr = -1; - for (int i = 0, oldCh = 0, isCof = 0; i < to; i++) - { - int ch = str.charAt(i); - if (ch > 32) - { - if (ch == '"') - while (++i < to && str.charAt(i) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); - if ((ch = (str.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < to && str.charAt(i) != '"'); - } - } - else - { - if (isOneOf(ch, operators)) - hasOpr = isCof = 0; - else if (oldCh <= 32 && isCof == 1) - return false; - else - isCof = 1; - } - } - oldCh = ch; - } - return hasOpr == 0; - } - - /** - * @return null -> 0, bool ? 1 : 0. Otherwise obj. - * - * @since 1.3.0 - */ - public static Object toNum(Object obj) - { - if (obj == null) - return 0; - if (obj instanceof Boolean) - return (boolean) obj ? 1 : 0; - if (obj instanceof Character) - return (int) (char) obj; - return obj; - } -} +package org.ugp.serialx.converters.operators; + +import static java.util.Arrays.asList; +import static org.ugp.serialx.utils.Utils.*; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; + +import org.ugp.serialx.GenericScope; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides arithmetics operators to evaluate mathematical expressions such as 5 * 2 +-- 2 / 2 ** 2 % 4 = 10! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ArithmeticOperators implements DataParser +{ + /** + * Operator characters recognized by {@link ArithmeticOperators}, operators can be any combination of provided characters. Exact behavior is handled by {@link ArithmeticOperators#operator}.
Intended for override, should not be null or empty! + * + * @since 1.3.8 + */ + protected char[] operators = {'+', '-', '*', '/', '%'}; + + @SuppressWarnings("unchecked") + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len; + if ((len = str.length()) > 2 && isExpression(str, len, operators)) + { + for (int i = 0; i < len; ) // Format duplicates of [+-]{2} + if (isOneOf(str.charAt(i++), '+', '-') && i < len && isOneOf(str.charAt(i), '+', '-')) + { + len = (str = fastReplace(fastReplace(fastReplace(fastReplace(str, "-+", "-"), "+-", "-"), "--", "+"), "++", "+")).length(); + i--; + } + + List[] terms = getAndParseTerms(str, len, myHomeRegistry, args, getClass(), operators); + ArrayList cofs = (ArrayList) terms[0]; + if (cofs.size() <= 1) + return cofs.get(0); + LinkedList oprs = (LinkedList) terms[1]; + + String op = null; + int index = 1; + try + { + for (int opPrio = getHighestPriority(); opPrio > 0; opPrio--) + for (ListIterator iter = oprs.listIterator(); iter.hasNext(); ) + { + if (getOperatorPriority(op = iter.next()) == opPrio) + { + iter.remove(); + cofs.set(index = iter.nextIndex(), operator(cofs.get(index), op, cofs.remove(index + 1), myHomeRegistry, args)); + } + } + + for (index = 1; (op = oprs.poll()) != null; ) + cofs.set(0, operator(cofs.get(0), op, cofs.get(index++), myHomeRegistry, args)); + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Arithmetic operator " + op + " is undefined between provided operands because " + ex.getMessage() + "!", ex); + } + catch (IndexOutOfBoundsException ex) + { + LogProvider.instance.logErr("Missing operand in \"" + str + "\"!", null); + } + catch (ArithmeticException ex) + { + LogProvider.instance.logErr(ex.getMessage(), ex); + } + + return cofs.get(0); + } + return CONTINUE; + } + + /** + * @param opr1 | Operand 1 + * @param op | The operator/operation + * @param opr2 | Operand 2 + * @param myHomeRegistry | Registry provided by the caller, use only in special cases! + * @param args | Some additional args provided by the caller for the myHomeRegistry, use only in special cases! + * + * @return Result of binary operation described by op between opr1 and opr2! If operator is not known, opr1 will be returned by default! + * + * @since 1.3.8 + */ + public Object operator(Object opr1, String op, Object opr2, ParserRegistry myHomeRegistry, Object... args) + { +// System.err.println(opr1 + op + opr2); + switch (op.charAt(0)) + { + case '+': + return addOperator(opr1, opr2); + case '-': + return subOperator(opr1, opr2); + case '*': + if (op.length() > 1 && op.charAt(1) == '*') + return powOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + return multOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + case '/': + return divOperator(opr1, opr2, op.endsWith("-") ? -1 : 1); + case '%': + return modOperator(opr1, opr2); + } + return opr1; + } + + /** + * @param op | The operator/operation + * + * @return Priority of provided operator (higher number = higher priority, 2 = high, 1 = medium, 0 = low) + * + * @see ArithmeticOperators#getHighestPriority() + * + * @since 1.3.8 + */ + public byte getOperatorPriority(String op) + { + switch (op.charAt(0)) + { + case '+': + case '-': + return 0; // Low + case '*': + if (op.length() > 1 && op.charAt(1) == '*') + return 2; // High ** + default: + return 1; // Medium * / % + } + } + + /** + * @return Number representing highest possible priority of operator (default is 2). + * + * @since 1.3.9 + */ + protected byte getHighestPriority() + { + return 2; + } + + /** + * @return Addition of cof and cof2 (cof + cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object addOperator(Object cof, Object cof2) + { + return add(toNum(cof), cof instanceof String ? cof2 : toNum(cof2)); + } + + /** + * @return Subtraction of cof and cof2 (cof - cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object subOperator(Object cof, Object cof2) + { + return sub(toNum(cof), toNum(cof2)); + } + + /** + * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign) supposed to be returned! + * + * @since 1.3.2 + */ + public Object multOperator(Object cof, Object cof2, int sign) + { + return mult(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign) supposed to be returned! + * + * @since 1.3.2 + */ + public Object divOperator(Object cof, Object cof2, int sign) + { + return div(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Modulation of cod and cof2 (cof % cof2) supposed to be returned! + * + * @since 1.3.2 + */ + public Object modOperator(Object cof, Object cof2) + { + return mod(toNum(cof), toNum(cof2)); + } + + /** + * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign)) supposed to be returned! + * + * @since 1.3.2 + */ + public Object powOperator(Object cof, Object cof2, int sign) + { + return pow(toNum(cof), toNum(cof2), sign); + } + + /** + * @return Addition of cof and cof2 (cof + cof2)! + * + * @since 1.3.0 + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object add(Object cof, Object cof2) + { + if (cof instanceof Number && cof2 instanceof Number) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() + ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() + ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() + ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() + ((Number) cof2).doubleValue(); + } + + if (cof.getClass().isArray()) + return mergeArrays(cof, cof2); + + if (cof instanceof Collection) + { + if (cof2 instanceof Collection) + ((Collection) cof).addAll(((Collection) cof2)); + else if (cof2.getClass().isArray()) + ((Collection) cof).addAll(asList(fromAmbiguousArray(cof2))); + else + ((Collection) cof).add(cof2); + return cof; + } + + if (cof instanceof GenericScope) + { + if (cof2 instanceof GenericScope) + ((GenericScope) cof).addAll(((GenericScope) cof2)); + else if (cof2 instanceof Collection) + ((GenericScope) cof).addAll((Collection) cof2); + else if (cof2.getClass().isArray()) + ((GenericScope) cof).addAll(fromAmbiguousArray(cof2)); + else + ((GenericScope) cof).add(cof2); + return cof; + } + return String.valueOf(cof) + String.valueOf(cof2); + } + + /** + * @return Subtraction of cof and cof2 (cof - cof2)! + * + * @since 1.3.0 + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static Object sub(Object cof, Object cof2) + { + if (cof instanceof Number && cof2 instanceof Number) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() - ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() - ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() - ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() - ((Number) cof2).doubleValue(); + } + + if (cof instanceof Collection) + { + if (cof2 instanceof Collection) + ((Collection) cof).removeAll(((Collection) cof2)); + else if (cof2.getClass().isArray()) + ((Collection) cof).removeAll(asList(fromAmbiguousArray(cof2))); + else + ((Collection) cof).remove(cof2); + return cof; + } + + if (cof instanceof GenericScope) + { + if (cof2 instanceof Collection) + ((GenericScope) cof).values().removeAll((Collection) cof2); + else if (cof2.getClass().isArray()) + ((GenericScope) cof).values().removeAll(asList(cof2)); + else + ((GenericScope) cof).values().remove(cof2); + return cof; + } + + return null; + } + + /** + * @return Multiplication of cof and cof2 multiplied by sign (cof * cof2 * sign)! + * + * @since 1.3.0 + */ + public static Object mult(Object cof, Object cof2, int sign) + { + if (cof2 instanceof Number) + { + if (!(cof instanceof Number)) + return multilpy(cof.toString(), ((Number) cof2).intValue() * sign).toString(); + + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() * ((Number) cof2).floatValue() * sign; + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() * ((Number) cof2).intValue() * sign; + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() * ((Number) cof2).longValue() * sign; + + return ((Number) cof).doubleValue() * ((Number) cof2).doubleValue() * sign; + } + + return multilpy(cof2.toString(), ((Number) cof).intValue() * sign).toString(); + } + + /** + * @return Division of cof and cof2 multiplied by sign (cof / cof2 * sign)! + * + * @since 1.3.0 + */ + public static Object div(Object cof, Object cof2, int sign) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() / ((Number) cof2).floatValue() * sign; + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() / ((Number) cof2).intValue() * sign; + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() / ((Number) cof2).longValue() * sign; + + return ((Number) cof).doubleValue() / ((Number) cof2).doubleValue() * sign; + } + + /** + * @return Modulation of cod and cof2 (cof % cof2)! + * + * @since 1.3.0 + */ + public static Object mod(Object cof, Object cof2) + { + if (cof instanceof Double || cof2 instanceof Double) + return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); + if (cof instanceof Float || cof2 instanceof Float) + return ((Number) cof).floatValue() % ((Number) cof2).floatValue(); + if (cof instanceof Integer || cof2 instanceof Integer) + return ((Number) cof).intValue() % ((Number) cof2).intValue(); + if (cof instanceof Long || cof2 instanceof Long) + return ((Number) cof).longValue() % ((Number) cof2).longValue(); + + return ((Number) cof).doubleValue() % ((Number) cof2).doubleValue(); + } + + /** + * @return Cof powered by cof2 multiplied by sign (Math.pow(cof, cof2 * sign))! + * + * @since 1.3.0 + */ + public static Object pow(Object cof, Object cof2, int sign) + { + double pow = Math.pow(((Number) cof).doubleValue(), ((Number) cof2).doubleValue() * sign); + if (pow > Long.MAX_VALUE || pow < Long.MIN_VALUE || cof instanceof Double || cof2 instanceof Double) + return pow; + if (pow <= Float.MAX_VALUE && pow >= Float.MIN_VALUE && (cof instanceof Float || cof2 instanceof Float)) + return (float) pow; + + if (pow > Integer.MAX_VALUE || pow < Integer.MIN_VALUE || cof instanceof Long || cof2 instanceof Long) + return (long) pow; + if (cof instanceof Integer || cof2 instanceof Integer) + return (int) pow; + return pow; + } + + /** + * @param str | String to split! + * @param to | Ending index of parsing, exclusive. Everything from this index to the end will be ignored (should be str.length())! + * @param registryForParsers | Registry to use for parsing operands! + * @param argsForParsers | Arguments for the parse method! + * @param classToIgnore | Parser to ignore (should be class of the caller if possible)! + * @param oprs | Operators to use as a splitters. 1 or more of these in row will be used as delimiter! + * + * @return Array with 2 lists. Index 0 is {@link ArrayList} containing parsed operands of the expression, index 1 is {@link LinkedList} containing operators of the expression! + * + * @since 1.3.8 (originally getTerms since 1.3.0) + */ + @SuppressWarnings("unchecked") + public static List[] getAndParseTerms(String str, int to, ParserRegistry registryForParsers, Object[] argsForParsers, Class classToIgnore, char... oprs) + { + List[] ret = new List[] {new ArrayList(), new LinkedList()}; //cofs, ops + + int i = 0, startIndex = 0, type = 0; + for (; i < to && isOneOf(str.charAt(i), oprs); i++); //in case of start cof sign + + for (int quote = 0, brackets = 0, lastType = type; i < to; i++) + { + char ch = str.charAt(i); + if (ch == '\"') + quote++; + else if ((ch | ' ') == '{') + brackets++; + else if ((ch | ' ') == '}') + brackets--; + else if (type == 1 || quote % 2 == 0 && brackets == 0) + { + if ((type = isOneOf(ch, oprs) ? 1 : 0) != lastType) + { + String s = str.substring(startIndex, i).trim(); + if (!s.isEmpty()) + ret[lastType].add(lastType == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); + startIndex = i; + } + else + type = lastType; + } + + lastType = type; + } + + String s = str.substring(startIndex, to).trim(); + if (!s.isEmpty()) + ret[type].add(type == 0 ? registryForParsers.parse(s, false, classToIgnore, argsForParsers) : s); +// System.err.println(ret[0] + "\n" + ret[1] + "\n"); + return ret; + } + + /** + * @param str | String that might be an expression! + * @param to | Ending index of checking, exclusive (should be str.length())! + * @param operators | Operators that str must have! + * + * @return True if inserted string is expression with any coefficients splitted by operators! + * + * @since 1.3.2 + */ + public static boolean isExpression(CharSequence str, int to, char... operators) + { + int hasOpr = -1; + for (int i = 0, oldCh = 0, isCof = 0; i < to; i++) + { + int ch = str.charAt(i); + if (ch > 32) + { + if (ch == '"') + while (++i < to && str.charAt(i) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < to && str.charAt(i) != '"'); + } + } + else + { + if (isOneOf(ch, operators)) + hasOpr = isCof = 0; + else if (oldCh <= 32 && isCof == 1) + return false; + else + isCof = 1; + } + } + oldCh = ch; + } + return hasOpr == 0; + } + + /** + * @return null -> 0, bool ? 1 : 0. Otherwise obj. + * + * @since 1.3.0 + */ + public static Object toNum(Object obj) + { + if (obj == null) + return 0; + if (obj instanceof Boolean) + return (boolean) obj ? 1 : 0; + if (obj instanceof Character) + return (int) (char) obj; + return obj; + } +} diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index 39bbedd..afca4d6 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -1,185 +1,185 @@ -package org.ugp.serialx.converters.operators; - -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; - -import java.lang.reflect.Array; -import java.util.Collection; -import java.util.Map; -import java.util.Objects; - -import org.ugp.serialx.Scope; -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.converters.imports.ImportsProvider; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides comparison operators, > < >= <= == === != !=== and instanceof, to compare 2 objects! For example 6 > 5, 1 < 5 or 5 == 5 returns true! - * - * @author PETO - * - * @since 1.3.0 - */ -public class ComparisonOperators implements DataParser -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len; - if ((len = str.length()) < 3) - return CONTINUE; - - int index, op; - if ((index = indexOfNotInObj(str, 0, len, -1, true, '<', '>', '=')) > -1) - { - if ((op = str.charAt(index)) != '=') // > < - { - boolean orEqual = index+1 < len && str.charAt(index+1) == '='; - return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), op == '>', orEqual); - } - - if (/*op == '=' &&*/ str.charAt(index+1) == '=') // == - { - boolean isTripple = index+2 < len && str.charAt(index+2) == '='; - return equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); - } - if (/*op == '=' &&*/ str.charAt(--index) == '!') // != - { - boolean isTripple = index+2 < len && str.charAt(index+2) == '='; - return !equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); - } - //System.out.println(str); - } - - if ((index = indexOfNotInObj(str, " instanceof ")) > -1) - { - try - { - return ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(index+12).trim()).isInstance(myHomeRegistry.parse(str.substring(0, index).trim(), args)); - } - catch (Exception e) - { - LogProvider.instance.logErr("Unable to check if object " + str.substring(0, index).trim() + " is instance of class \"" + str.substring(index+12).trim() + "\" because there is no such a class!", e); - return null; - } - } - //double t = System.nanoTime(); - //System.out.println((t-t0)/1000000); - return CONTINUE; - } - - /** - * @param obj1 | Object 1! - * @param obj2 | Object 2! - * @param compareInstances | If true, this method will compare objects using == operator! - * - * @return True supposed to be returned if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! - * - * @since 1.3.2 - */ - public boolean equalsOperator(Object obj1, Object obj2, boolean compareInstances) - { - return equals(obj1, obj2, compareInstances); - } - - /** - * @param obj1 | Object 1! - * @param obj2 | Object 2 to be compared with Object 1! - * @param isGreater | If true, Object 1 must be greater than Object 2 in order for true to be returned! - * @param orEqual | If true, Object 1 being numerically equal to Object 2 will result in true to be returned! - * - * @return True supposed to be returned according to arguments! - * - * @since 1.3.2 - */ - @SuppressWarnings("unchecked") - public Object comparisonOperator(Object obj1, Object obj2, boolean isGreater, boolean orEqual) - { - try - { - return numberComparator(((Number) (obj1 = toCompareFriendly(obj1))).doubleValue(), ((Number) (obj2 = toCompareFriendly(obj2))).doubleValue(), isGreater, orEqual); - } - catch (ClassCastException ex) - { - if (obj1 instanceof Comparable) - return numberComparator(((Comparable) obj1).compareTo(obj2), 0, isGreater, orEqual); - - LogProvider.instance.logErr("Comparison operator is undefined between " + obj1.getClass().getName() + " and " + obj2.getClass().getName() + "!", ex); - return null; - } - } - - /** - * @return {@link Map} -> {@link Map#size()}, {@link Collection} -> {@link Collection#size()}, {@link CharSequence} -> {@link CharSequence#length()}, array -> array.length otherwise {@link ArithmeticOperators#toNum(Object)} - * - * @since 1.3.0 - */ - public static Object toCompareFriendly(Object obj) - { - if (obj instanceof Map) - return ((Map) obj).size(); - if (obj instanceof Collection) - return ((Collection) obj).size(); - if (obj instanceof Scope) - return ((Scope) obj).valuesCount() + ((Scope) obj).variablesCount(); - if (obj instanceof CharSequence) - return ((CharSequence) obj).length(); - if ((obj = ArithmeticOperators.toNum(obj)).getClass().isArray()) - return Array.getLength(obj); - return obj; - } - - /** - * @param d1 | Number 1! - * @param d2 | Number 2 to be compared with number 1! - * @param isGreater | If true, number 1 must be greater than number 2 in order for true to be returned! - * @param orEqual | If true, number 1 being equal to number 2 will result in true to be returned! - * - * @return True according to arguments! - * - * @since 1.3.2 - */ - public static boolean numberComparator(double d1, double d2, boolean isGreater, boolean orEqual) - { - return isGreater ? (orEqual ? d1 >= d2 : d1 > d2) : (orEqual ? d1 <= d2 : d1 < d2); - } - - /** - * @param obj1 | Object 1! - * @param obj2 | Object 2! - * - * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! - * - * @since 1.3.0 - */ - public static boolean equals(Object obj1, Object obj2) - { - return equals(obj1, obj2, false); - } - - /** - * @param obj1 | Object 1! - * @param obj2 | Object 2! - * @param compareInstances | If true, this method will compare objects using == operator! - * - * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! - * - * @since 1.3.2 - */ - public static boolean equals(Object obj1, Object obj2, boolean compareInstances) - { - return compareInstances ? obj1 == obj2 || obj1 != null && obj2 != null && obj1.getClass() == obj2.getClass() && numericallyEquals(obj1, obj2) : Objects.deepEquals(obj1, obj2) || numericallyEquals(obj1, obj2); - } - - /** - * @param obj1 | Object 1! - * @param obj2 | Object 2! - * - * @return True if obj1 numerically equals to obj2! For instance true == 1, null == 0! - * - * @since 1.3.2 - */ - public static boolean numericallyEquals(Object obj1, Object obj2) - { - return (obj1 = ArithmeticOperators.toNum(obj1)) instanceof Number && (obj2 = ArithmeticOperators.toNum(obj2)) instanceof Number && ((Number) obj1).doubleValue() == ((Number) obj2).doubleValue(); - } -} +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; + +import java.lang.reflect.Array; +import java.util.Collection; +import java.util.Map; +import java.util.Objects; + +import org.ugp.serialx.Scope; +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.converters.imports.ImportsProvider; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides comparison operators, > < >= <= == === != !=== and instanceof, to compare 2 objects! For example 6 > 5, 1 < 5 or 5 == 5 returns true! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ComparisonOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len; + if ((len = str.length()) < 3) + return CONTINUE; + + int index, op; + if ((index = indexOfNotInObj(str, 0, len, -1, true, '<', '>', '=')) > -1) + { + if ((op = str.charAt(index)) != '=') // > < + { + boolean orEqual = index+1 < len && str.charAt(index+1) == '='; + return comparisonOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (orEqual ? 2 : 1)).trim(), args), op == '>', orEqual); + } + + if (/*op == '=' &&*/ str.charAt(index+1) == '=') // == + { + boolean isTripple = index+2 < len && str.charAt(index+2) == '='; + return equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + } + if (/*op == '=' &&*/ str.charAt(--index) == '!') // != + { + boolean isTripple = index+2 < len && str.charAt(index+2) == '='; + return !equalsOperator(myHomeRegistry.parse(str.substring(0, index).trim(), args), myHomeRegistry.parse(str.substring(index + (isTripple ? 3 : 2)).trim(), args), isTripple); + } + //System.out.println(str); + } + + if ((index = indexOfNotInObj(str, " instanceof ")) > -1) + { + try + { + return ImportsProvider.forName(args.length > 0 ? args[0] : null, str.substring(index+12).trim()).isInstance(myHomeRegistry.parse(str.substring(0, index).trim(), args)); + } + catch (Exception e) + { + LogProvider.instance.logErr("Unable to check if object " + str.substring(0, index).trim() + " is instance of class \"" + str.substring(index+12).trim() + "\" because there is no such a class!", e); + return null; + } + } + //double t = System.nanoTime(); + //System.out.println((t-t0)/1000000); + return CONTINUE; + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * @param compareInstances | If true, this method will compare objects using == operator! + * + * @return True supposed to be returned if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.2 + */ + public boolean equalsOperator(Object obj1, Object obj2, boolean compareInstances) + { + return equals(obj1, obj2, compareInstances); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2 to be compared with Object 1! + * @param isGreater | If true, Object 1 must be greater than Object 2 in order for true to be returned! + * @param orEqual | If true, Object 1 being numerically equal to Object 2 will result in true to be returned! + * + * @return True supposed to be returned according to arguments! + * + * @since 1.3.2 + */ + @SuppressWarnings("unchecked") + public Object comparisonOperator(Object obj1, Object obj2, boolean isGreater, boolean orEqual) + { + try + { + return numberComparator(((Number) (obj1 = toCompareFriendly(obj1))).doubleValue(), ((Number) (obj2 = toCompareFriendly(obj2))).doubleValue(), isGreater, orEqual); + } + catch (ClassCastException ex) + { + if (obj1 instanceof Comparable) + return numberComparator(((Comparable) obj1).compareTo(obj2), 0, isGreater, orEqual); + + LogProvider.instance.logErr("Comparison operator is undefined between " + obj1.getClass().getName() + " and " + obj2.getClass().getName() + "!", ex); + return null; + } + } + + /** + * @return {@link Map} -> {@link Map#size()}, {@link Collection} -> {@link Collection#size()}, {@link CharSequence} -> {@link CharSequence#length()}, array -> array.length otherwise {@link ArithmeticOperators#toNum(Object)} + * + * @since 1.3.0 + */ + public static Object toCompareFriendly(Object obj) + { + if (obj instanceof Map) + return ((Map) obj).size(); + if (obj instanceof Collection) + return ((Collection) obj).size(); + if (obj instanceof Scope) + return ((Scope) obj).valuesCount() + ((Scope) obj).variablesCount(); + if (obj instanceof CharSequence) + return ((CharSequence) obj).length(); + if ((obj = ArithmeticOperators.toNum(obj)).getClass().isArray()) + return Array.getLength(obj); + return obj; + } + + /** + * @param d1 | Number 1! + * @param d2 | Number 2 to be compared with number 1! + * @param isGreater | If true, number 1 must be greater than number 2 in order for true to be returned! + * @param orEqual | If true, number 1 being equal to number 2 will result in true to be returned! + * + * @return True according to arguments! + * + * @since 1.3.2 + */ + public static boolean numberComparator(double d1, double d2, boolean isGreater, boolean orEqual) + { + return isGreater ? (orEqual ? d1 >= d2 : d1 > d2) : (orEqual ? d1 <= d2 : d1 < d2); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.0 + */ + public static boolean equals(Object obj1, Object obj2) + { + return equals(obj1, obj2, false); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * @param compareInstances | If true, this method will compare objects using == operator! + * + * @return True if obj1 equals to obj2 otherwise false similar to {@link Objects#deepEquals(Object, Object)} but this one can handle OOP crosstype number compression such as {@link Integer} and {@link Double}! + * + * @since 1.3.2 + */ + public static boolean equals(Object obj1, Object obj2, boolean compareInstances) + { + return compareInstances ? obj1 == obj2 || obj1 != null && obj2 != null && obj1.getClass() == obj2.getClass() && numericallyEquals(obj1, obj2) : Objects.deepEquals(obj1, obj2) || numericallyEquals(obj1, obj2); + } + + /** + * @param obj1 | Object 1! + * @param obj2 | Object 2! + * + * @return True if obj1 numerically equals to obj2! For instance true == 1, null == 0! + * + * @since 1.3.2 + */ + public static boolean numericallyEquals(Object obj1, Object obj2) + { + return (obj1 = ArithmeticOperators.toNum(obj1)) instanceof Number && (obj2 = ArithmeticOperators.toNum(obj2)) instanceof Number && ((Number) obj1).doubleValue() == ((Number) obj2).doubleValue(); + } +} diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index d0f7a39..554f2f0 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -1,141 +1,141 @@ -package org.ugp.serialx.converters.operators; - -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides conditional assignment operators more specially ternary and null coalescing! For example true ? "Yes" : "No" will return "Yes" and null ?? "Hello!" will return hello! - * - * @author PETO - * - * @since 1.3.0 - */ -public class ConditionalAssignmentOperators implements DataParser -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int index, ternIfIndex; - if (str.length() > 2 && (index = indexOfNotInObj(str, '?')) > -1) - { - if ((ternIfIndex = indexOfOne(str, index, '?')) > -1) //?: - { - try - { - String last = str.substring((index = ternIfIndex)+1), first = str.substring(0, index); - boolean condition = (boolean) LogicalOperators.toBool(myHomeRegistry.parse(first.trim(), args)); - if ((index = indexOfTernaryElse(last, 1, '?', ':')) > -1) - { - first = last.substring(0, index); - return condition ? myHomeRegistry.parse(first.trim(), args) : (last = last.substring(index+1).trim()).isEmpty() ? VOID : myHomeRegistry.parse(last, args); - } - return condition ? myHomeRegistry.parse(last.trim(), args) : VOID; - } - catch (ClassCastException ex) - { - LogProvider.instance.logErr(str.substring(0, index).trim() + " is invalid condition for ternary operator! Condition must be boolean, try to insert \"!= null\" check!", ex); - return null; - } - } - - if (str.charAt(index+1) == '?') //?? - { - Object obj ; - if ((obj = myHomeRegistry.parse(str.substring(0, index).trim(), args)) != null) - return obj; - - String next = str.substring(index+2); - if ((next = next.trim()).isEmpty()) - return null; - return myHomeRegistry.parse(next, args); - } - } - return CONTINUE; - } - - /** - * @param str | Source string to search. - * @param defaultCountOfConfitions | How many condition operators (tenraryTokens[0]) are expected. Should be 1 in most cases. - * @param ternaryOperators | Characters representing parts of ternary operator. Index 0 should be '?' and index 1 should be ':'. - * - * @return Return index of else branch in ternary operator expression or -1 if there is no else branch! - * - * @since 1.3.5 - */ - public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) - { - for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0; i < len; i++) - { - int ch = str.charAt(i); - if (ch == '\"') - while (++i < len && str.charAt(i) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); - if ((ch = (str.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && str.charAt(i) != '"'); - } - } - else - { - for (char token : ternaryOperators) - if (ch == token && oldCh != token && (i >= len-1 || str.charAt(i+1) != token)) - { - defaultCountOfConfitions += token == ternaryOperators[0] ? 1 : -1; - tokenCount++; - } - - if (defaultCountOfConfitions == 0 && tokenCount > 0) - return i; - } - oldCh = ch; - } - return -1; - } - - /** - * @param str | String to search. - * @param from | Beginning index. Should be 0 in most cases. - * @param oneChar | Single character that you want to find. - * - * @return Index of oneChar if there is only one in a row! - * - * @since 1.3.5 - */ - public static int indexOfOne(CharSequence str, int from, char oneChar) - { - for (int len = str.length(), oldCh = -1; from < len; from++) - { - int ch = str.charAt(from); - if (ch == '\"') - while (++from < len && str.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); - if ((ch = (str.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < len && str.charAt(from) != '"'); - } - } - else if (ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) - return from; - oldCh = ch; - } - return -1; - } -} +package org.ugp.serialx.converters.operators; + +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides conditional assignment operators more specially ternary and null coalescing! For example true ? "Yes" : "No" will return "Yes" and null ?? "Hello!" will return hello! + * + * @author PETO + * + * @since 1.3.0 + */ +public class ConditionalAssignmentOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int index, ternIfIndex; + if (str.length() > 2 && (index = indexOfNotInObj(str, '?')) > -1) + { + if ((ternIfIndex = indexOfOne(str, index, '?')) > -1) //?: + { + try + { + String last = str.substring((index = ternIfIndex)+1), first = str.substring(0, index); + boolean condition = (boolean) LogicalOperators.toBool(myHomeRegistry.parse(first.trim(), args)); + if ((index = indexOfTernaryElse(last, 1, '?', ':')) > -1) + { + first = last.substring(0, index); + return condition ? myHomeRegistry.parse(first.trim(), args) : (last = last.substring(index+1).trim()).isEmpty() ? VOID : myHomeRegistry.parse(last, args); + } + return condition ? myHomeRegistry.parse(last.trim(), args) : VOID; + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr(str.substring(0, index).trim() + " is invalid condition for ternary operator! Condition must be boolean, try to insert \"!= null\" check!", ex); + return null; + } + } + + if (str.charAt(index+1) == '?') //?? + { + Object obj ; + if ((obj = myHomeRegistry.parse(str.substring(0, index).trim(), args)) != null) + return obj; + + String next = str.substring(index+2); + if ((next = next.trim()).isEmpty()) + return null; + return myHomeRegistry.parse(next, args); + } + } + return CONTINUE; + } + + /** + * @param str | Source string to search. + * @param defaultCountOfConfitions | How many condition operators (tenraryTokens[0]) are expected. Should be 1 in most cases. + * @param ternaryOperators | Characters representing parts of ternary operator. Index 0 should be '?' and index 1 should be ':'. + * + * @return Return index of else branch in ternary operator expression or -1 if there is no else branch! + * + * @since 1.3.5 + */ + public static int indexOfTernaryElse(CharSequence str, int defaultCountOfConfitions, char... ternaryOperators) + { + for (int i = 0, len = str.length(), oldCh = -1, tokenCount = 0; i < len; i++) + { + int ch = str.charAt(i); + if (ch == '\"') + while (++i < len && str.charAt(i) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && str.charAt(i) != '"'); + } + } + else + { + for (char token : ternaryOperators) + if (ch == token && oldCh != token && (i >= len-1 || str.charAt(i+1) != token)) + { + defaultCountOfConfitions += token == ternaryOperators[0] ? 1 : -1; + tokenCount++; + } + + if (defaultCountOfConfitions == 0 && tokenCount > 0) + return i; + } + oldCh = ch; + } + return -1; + } + + /** + * @param str | String to search. + * @param from | Beginning index. Should be 0 in most cases. + * @param oneChar | Single character that you want to find. + * + * @return Index of oneChar if there is only one in a row! + * + * @since 1.3.5 + */ + public static int indexOfOne(CharSequence str, int from, char oneChar) + { + for (int len = str.length(), oldCh = -1; from < len; from++) + { + int ch = str.charAt(from); + if (ch == '\"') + while (++from < len && str.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + str); + if ((ch = (str.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < len && str.charAt(from) != '"'); + } + } + else if (ch == oneChar && oldCh != oneChar && (from >= len-1 || str.charAt(from+1) != oneChar)) + return from; + oldCh = ch; + } + return -1; + } +} diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index 250e907..1a17f78 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -1,133 +1,133 @@ -package org.ugp.serialx.converters.operators; - -import static java.lang.Boolean.FALSE; -import static java.lang.Boolean.TRUE; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.multilpy; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides logical operators to evaluate boolean expressions such as false || true && true ^ false = true! - * - * @author PETO - * - * @since 1.3.0 - */ -public class LogicalOperators implements DataParser -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) - { - int len; - if ((len = s.length()) < 3) - return CONTINUE; - - Object result = CONTINUE; - int i = 0, index, op = 0, nextOpIndex; - try - { - do - { - if ((index = indexOfNotInObj(s, i, len, -1, true, '&', '|', '^')) == -1) - return result; //CONTINUE; - if ((op = s.charAt(i = index)) != '^' && (++i >= len || s.charAt(i) != op)) // Ensure && and || and refuse & and | - continue; - - if (result == CONTINUE) // Beginning - result = myHomeRegistry.parse(s.substring(0, index).trim(), args); - - if (op == '|') - { - if (TRUE.equals(result)) - return TRUE; - - nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); - result = orOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); - } - else if (op == '&') - { - if (FALSE.equals(result)) - { - i = indexOfNotInObj(s, ++i, len, len, true, '|', '^'); - continue; - } - - nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); - result = andOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); - } - else - { - nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); - result = xorOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); - } - - i = nextOpIndex; - } - while (i < len); - } - catch (ClassCastException ex) - { - LogProvider.instance.logErr("Logical operator " + multilpy((char) op, op != '^' ? 2 : 1) + " is undefined between provided operands because " + ex.getMessage() + "!", ex); - } - - return result; - } - - /** - * @return True if obj1 and obj2 is true! - * - * @since 1.3.2 - */ - public Object andOperator(Object obj1, Object obj2) - { - return (boolean) toBool(obj1) && (boolean) toBool(obj2); - } - - /** - * @return True if obj1 or obj2 is true! - * - * @since 1.3.2 - */ - public Object orOperator(Object obj1, Object obj2) - { - return (boolean) toBool(obj1) || (boolean) toBool(obj2); - } - - /** - * @return True if obj1 xor obj2 is true! - * - * @since 1.3.2 - */ - public Object xorOperator(Object obj1, Object obj2) - { - return (boolean) toBool(obj1) ^ (boolean) toBool(obj2); - } - - /** - * @return null -> false or if number > 0. Otherwise obj. - * - * @since 1.3.0 - */ - public static Object toBool(Object obj) - { - if (obj == null) - return FALSE; - if (obj instanceof Number) - return ((Number) obj).doubleValue() != 0; - if (obj instanceof Character) - return (char) obj != 0; -// if (obj instanceof CharSequence) -// return ((CharSequence) obj).length() > 0; -// if (obj instanceof Map) -// return !((Map) obj).isEmpty(); -// if (obj instanceof Collection) -// return !((Collection) obj).isEmpty(); -// if (obj instanceof Scope) -// return !((Scope) obj).isEmpty(); -// if (obj.getClass().isArray()) -// return Array.getLength(obj) > 0; - return obj; - } +package org.ugp.serialx.converters.operators; + +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.Utils.multilpy; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides logical operators to evaluate boolean expressions such as false || true && true ^ false = true! + * + * @author PETO + * + * @since 1.3.0 + */ +public class LogicalOperators implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String s, Object... args) + { + int len; + if ((len = s.length()) < 3) + return CONTINUE; + + Object result = CONTINUE; + int i = 0, index, op = 0, nextOpIndex; + try + { + do + { + if ((index = indexOfNotInObj(s, i, len, -1, true, '&', '|', '^')) == -1) + return result; //CONTINUE; + if ((op = s.charAt(i = index)) != '^' && (++i >= len || s.charAt(i) != op)) // Ensure && and || and refuse & and | + continue; + + if (result == CONTINUE) // Beginning + result = myHomeRegistry.parse(s.substring(0, index).trim(), args); + + if (op == '|') + { + if (TRUE.equals(result)) + return TRUE; + + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); + result = orOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + else if (op == '&') + { + if (FALSE.equals(result)) + { + i = indexOfNotInObj(s, ++i, len, len, true, '|', '^'); + continue; + } + + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); + result = andOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + else + { + nextOpIndex = indexOfNotInObj(s, ++i, len, len, true, '&', '|', '^'); + result = xorOperator(result, myHomeRegistry.parse(s.substring(i, nextOpIndex).trim(), args)); + } + + i = nextOpIndex; + } + while (i < len); + } + catch (ClassCastException ex) + { + LogProvider.instance.logErr("Logical operator " + multilpy((char) op, op != '^' ? 2 : 1) + " is undefined between provided operands because " + ex.getMessage() + "!", ex); + } + + return result; + } + + /** + * @return True if obj1 and obj2 is true! + * + * @since 1.3.2 + */ + public Object andOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) && (boolean) toBool(obj2); + } + + /** + * @return True if obj1 or obj2 is true! + * + * @since 1.3.2 + */ + public Object orOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) || (boolean) toBool(obj2); + } + + /** + * @return True if obj1 xor obj2 is true! + * + * @since 1.3.2 + */ + public Object xorOperator(Object obj1, Object obj2) + { + return (boolean) toBool(obj1) ^ (boolean) toBool(obj2); + } + + /** + * @return null -> false or if number > 0. Otherwise obj. + * + * @since 1.3.0 + */ + public static Object toBool(Object obj) + { + if (obj == null) + return FALSE; + if (obj instanceof Number) + return ((Number) obj).doubleValue() != 0; + if (obj instanceof Character) + return (char) obj != 0; +// if (obj instanceof CharSequence) +// return ((CharSequence) obj).length() > 0; +// if (obj instanceof Map) +// return !((Map) obj).isEmpty(); +// if (obj instanceof Collection) +// return !((Collection) obj).isEmpty(); +// if (obj instanceof Scope) +// return !((Scope) obj).isEmpty(); +// if (obj.getClass().isArray()) +// return Array.getLength(obj) > 0; + return obj; + } } \ No newline at end of file diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java index f5940ff..ed306b6 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/NegationOperator.java @@ -1,94 +1,94 @@ -package org.ugp.serialx.converters.operators; - -import org.ugp.serialx.converters.DataParser; -import org.ugp.serialx.utils.LogProvider; - -/** - * This parser provides ability to negate stuff! For example !true returns false!
- * This include classic numeric negation - and logical negation ! operators. - * - * @author PETO - * - * @since 1.3.0 - */ -public class NegationOperator implements DataParser -{ - @Override - public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) - { - int len, type; - if ((len = str.length()) < 2) - return CONTINUE; - if ((type = str.charAt(0)) == '!' || type == '-') - { - int negCount = 1; - for (int ch; negCount < len && ((ch = str.charAt(negCount)) == '!' || ch == '-'); negCount++); - - Object obj = myHomeRegistry.parse(str.substring(negCount).trim(), false, getClass(), args); - if (negCount % 2 == 0) - return obj; - - Object neg = type == '!' ? logicalNotOperator(obj) : notOperator(obj); - if (obj == neg && !(obj instanceof Number && ((Number) obj).intValue() == 0)) - LogProvider.instance.logErr("Unable to nagete \"" + obj + "\" because object of \"" + obj.getClass().getName() + "\" cant be negated!", null); - return neg; - } - return CONTINUE; - } - - - /** - * @param obj | Object to negate! Numeric in nature or an object! - * - * @return Negated object supposed to be returned or same object as argument if object can't be negated! Only numbers and booleans can be negated! - * - * @since 1.3.2 - */ - public Object notOperator(Object obj) - { - return negate(obj); - } - - /** - * @param obj | Object to negate! Should be boolean! - * - * @return Negated object supposed to be returned or same object as argument if object can't be negated! Should, but do not strictly has to be boolean!
- * Node: By default it has same behavior as {@link NegationOperator#notOperator(Object)} but it can be overridden! - * - * @since 1.3.8 - */ - public Object logicalNotOperator(Object obj) - { - return negate(obj); - } - - /** - * @param obj | Object to negate! - * - * @return Negated object or same object as argument if object can't be negated! Only numbers and booleans can be negated! - * - * @since 1.3.0 - */ - public static Object negate(Object obj) - { - if (obj == null) - return 0; - else if (obj instanceof Boolean) - obj = !((boolean) obj); - else if (obj.getClass() == Byte.class) - obj = (byte) -((Number) obj).byteValue(); - else if (obj.getClass() == Short.class) - obj = (short) -((Number) obj).shortValue(); - else if (obj.getClass() == Integer.class) - obj = -((int) obj); - else if (obj.getClass() == Character.class) - obj = (char) -((Character) obj); - else if (obj.getClass() == Long.class) - obj = -((long) obj); - else if (obj.getClass() == Float.class) - obj = -((float) obj); - else if (obj.getClass() == Double.class) - obj = -((double) obj); - return obj; - } -} +package org.ugp.serialx.converters.operators; + +import org.ugp.serialx.converters.DataParser; +import org.ugp.serialx.utils.LogProvider; + +/** + * This parser provides ability to negate stuff! For example !true returns false!
+ * This include classic numeric negation - and logical negation ! operators. + * + * @author PETO + * + * @since 1.3.0 + */ +public class NegationOperator implements DataParser +{ + @Override + public Object parse(ParserRegistry myHomeRegistry, String str, Object... args) + { + int len, type; + if ((len = str.length()) < 2) + return CONTINUE; + if ((type = str.charAt(0)) == '!' || type == '-') + { + int negCount = 1; + for (int ch; negCount < len && ((ch = str.charAt(negCount)) == '!' || ch == '-'); negCount++); + + Object obj = myHomeRegistry.parse(str.substring(negCount).trim(), false, getClass(), args); + if (negCount % 2 == 0) + return obj; + + Object neg = type == '!' ? logicalNotOperator(obj) : notOperator(obj); + if (obj == neg && !(obj instanceof Number && ((Number) obj).intValue() == 0)) + LogProvider.instance.logErr("Unable to nagete \"" + obj + "\" because object of \"" + obj.getClass().getName() + "\" cant be negated!", null); + return neg; + } + return CONTINUE; + } + + + /** + * @param obj | Object to negate! Numeric in nature or an object! + * + * @return Negated object supposed to be returned or same object as argument if object can't be negated! Only numbers and booleans can be negated! + * + * @since 1.3.2 + */ + public Object notOperator(Object obj) + { + return negate(obj); + } + + /** + * @param obj | Object to negate! Should be boolean! + * + * @return Negated object supposed to be returned or same object as argument if object can't be negated! Should, but do not strictly has to be boolean!
+ * Node: By default it has same behavior as {@link NegationOperator#notOperator(Object)} but it can be overridden! + * + * @since 1.3.8 + */ + public Object logicalNotOperator(Object obj) + { + return negate(obj); + } + + /** + * @param obj | Object to negate! + * + * @return Negated object or same object as argument if object can't be negated! Only numbers and booleans can be negated! + * + * @since 1.3.0 + */ + public static Object negate(Object obj) + { + if (obj == null) + return 0; + else if (obj instanceof Boolean) + obj = !((boolean) obj); + else if (obj.getClass() == Byte.class) + obj = (byte) -((Number) obj).byteValue(); + else if (obj.getClass() == Short.class) + obj = (short) -((Number) obj).shortValue(); + else if (obj.getClass() == Integer.class) + obj = -((int) obj); + else if (obj.getClass() == Character.class) + obj = (char) -((Character) obj); + else if (obj.getClass() == Long.class) + obj = -((long) obj); + else if (obj.getClass() == Float.class) + obj = -((float) obj); + else if (obj.getClass() == Double.class) + obj = -((double) obj); + return obj; + } +} diff --git a/pom.xml b/pom.xml index 5a705f3..ad26a13 100644 --- a/pom.xml +++ b/pom.xml @@ -1,152 +1,152 @@ - - 4.0.0 - - org.ugp - serialx - ${revision} - pom - - - SerialX-json - SerialX-core - SerialX-devtools - SerialX-operators - SerialX-juss - - - SerialX root - - Store Java objects into JSON or any format you want! SerialX is - a powerful lightweight utility library to serialize Java objects - programmatically via tweakable recursive descent parser for custom - domain-specific languages! - - https://github.com/SimplyProgrammer/Java-SerialX - 2020 - - - - Custom license - https://github.com/SimplyProgrammer/Java-SerialX/blob/master/LICENSE - - - - - - SimplyProgrammer - petko.hupka@gmail.com - org.ugp - https://github.com/SimplyProgrammer/ - - - - - scm:git:git://github.com/SimplyProgrammer/Java-SerialX.git - scm:git:ssh://github.com:SimplyProgrammer/Java-SerialX.git - https://github.com/SimplyProgrammer/ - - - - - github - https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX - - - - - - github - https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX - - - - - 8 - 4.0.0-SNAPSHOT - - UTF-8 - ${java.version} - ${java.version} - - - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.10.1 - - - ${java.version} - ${java.version} - - eclipse - - - - org.codehaus.plexus - plexus-compiler-eclipse - 2.9.0 - - - org.eclipse.jdt - ecj - 3.25.0 - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.8.0 - - - -Xdoclint:none - -Xdoclint:none - - - - - - jar - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - - jar - - - - - - org.codehaus.mojo - flatten-maven-plugin - 1.6.0 - - - - flatten - process-resources - - flatten - - - - - - + + 4.0.0 + + org.ugp + serialx + ${revision} + pom + + + SerialX-json + SerialX-core + SerialX-devtools + SerialX-operators + SerialX-juss + + + SerialX root + + Store Java objects into JSON or any format you want! SerialX is + a powerful lightweight utility library to serialize Java objects + programmatically via tweakable recursive descent parser for custom + domain-specific languages! + + https://github.com/SimplyProgrammer/Java-SerialX + 2020 + + + + Custom license + https://github.com/SimplyProgrammer/Java-SerialX/blob/master/LICENSE + + + + + + SimplyProgrammer + petko.hupka@gmail.com + org.ugp + https://github.com/SimplyProgrammer/ + + + + + scm:git:git://github.com/SimplyProgrammer/Java-SerialX.git + scm:git:ssh://github.com:SimplyProgrammer/Java-SerialX.git + https://github.com/SimplyProgrammer/ + + + + + github + https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX + + + + + + github + https://maven.pkg.github.com/SimplyProgrammer/Java-SerialX + + + + + 8 + 4.0.0-SNAPSHOT + + UTF-8 + ${java.version} + ${java.version} + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.10.1 + + + ${java.version} + ${java.version} + + eclipse + + + + org.codehaus.plexus + plexus-compiler-eclipse + 2.9.0 + + + org.eclipse.jdt + ecj + 3.25.0 + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.8.0 + + + -Xdoclint:none + -Xdoclint:none + + + + + + jar + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.1 + + + + jar + + + + + + org.codehaus.mojo + flatten-maven-plugin + 1.6.0 + + + + flatten + process-resources + + flatten + + + + + + \ No newline at end of file From d4bde7d9d76b8a6a7b81684572513698883b0b01 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 28 Sep 2026 16:08:23 +0200 Subject: [PATCH 71/75] codemr for core, juss and json --- .../serialx-core/graphs/all_bymodularity.cmr | 1 + .../serialx-core/graphs/all_bypackage.cmr | 1 + .../graphs/all_byprojectmodule.cmr | 1 + .../codemr/serialx-core/graphs/all_nm.cmr | 1 + .../graphs/all_nm_inheritance.cmr | 1 + .../html/graph_htmls/all_bymodularity.html | 1 + .../html/graph_htmls/all_bymodularity.png | Bin 0 -> 25490 bytes .../html/graph_htmls/all_bypackage.html | 1 + .../html/graph_htmls/all_bypackage.png | Bin 0 -> 32694 bytes .../html/graph_htmls/all_byprojectmodule.html | 1 + .../html/graph_htmls/all_byprojectmodule.png | Bin 0 -> 15339 bytes .../serialx-core/html/graph_htmls/all_nm.html | 1 + .../serialx-core/html/graph_htmls/all_nm.png | Bin 0 -> 25932 bytes .../html/graph_htmls/all_nm_inheritance.html | 1 + .../html/graph_htmls/all_nm_inheritance.png | Bin 0 -> 10401 bytes .../html/graph_htmls/graphlist.js | 1 + .../htmlx/Xdonut.html | 107 + .../htmlx/circlepack.html | 113 + .../htmlx/dependency.html | 31 + .../html_report_serialx-core/htmlx/donut.html | 179 + .../htmlx/donutcharts.html | 42 + .../htmlx/donutchartssimple.html | 26 + .../htmlx/lbd/README.md | 109 + .../htmlx/lbd/dashboard.html | 334 + .../htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../htmlx/lbd/notifications.html | 310 + .../htmlx/lbd/table.html | 446 + .../htmlx/lbd/template.html | 154 + .../htmlx/metricchartmethod.html | 27 + .../htmlx/metricchartpackage.html | 25 + .../htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 17 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 226 + .../htmlx/modeldata/table_data.js | 1 + .../htmlx/report.html | 28 + .../htmlx/reportforprint.html | 28 + .../htmlx/sunburst.html | 106 + .../htmlx/treemap.html | 56 + .../html/html_report_serialx-core/index.html | 1 + .../html/assets/css/animate.min.css | 6 + .../html/assets/css/bootstrap.min.css | 5 + .../html/main_report/html/assets/css/demo.css | 61 + .../html/assets/css/font-awesome.min.css | 4 + .../main_report/html/assets/css/helptip.css | 148 + .../assets/css/light-bootstrap-dashboard.css | 3393 ++++++ .../html/assets/css/pe-icon-7-stroke.css | 632 ++ .../html/assets/fonts/Pe-icon-7-stroke.eot | Bin 0 -> 58680 bytes .../html/assets/fonts/Pe-icon-7-stroke.svg | 212 + .../html/assets/fonts/Pe-icon-7-stroke.ttf | Bin 0 -> 58480 bytes .../html/assets/fonts/Pe-icon-7-stroke.woff | Bin 0 -> 58556 bytes .../html/assets/img/codemr-icon-black-1.png | Bin 0 -> 15510 bytes .../html/assets/img/codemr-white-32.png | Bin 0 -> 1254 bytes .../html/assets/img/default-avatar.png | Bin 0 -> 2864 bytes .../main_report/html/assets/img/favicon.ico | Bin 0 -> 1150 bytes .../html/assets/img/loading-bubbles.svg | 14 + .../html/main_report/html/assets/img/mask.png | Bin 0 -> 756 bytes .../main_report/html/assets/img/new_logo.png | Bin 0 -> 3557 bytes .../main_report/html/assets/img/sidebar-5.jpg | Bin 0 -> 280836 bytes .../js/bootstrap-checkbox-radio-switch.js | 502 + .../html/assets/js/bootstrap-notify.js | 404 + .../html/assets/js/bootstrap-select.js | 438 + .../html/assets/js/bootstrap.min.js | 7 + .../html/assets/js/chartist.min.js | 9 + .../html/main_report/html/assets/js/demo.js | 152 + .../html/assets/js/jquery-1.10.2.js | 9789 +++++++++++++++++ .../assets/js/light-bootstrap-dashboard.js | 159 + .../html/assets/sass/lbd/_alerts.scss | 82 + .../html/assets/sass/lbd/_buttons.scss | 108 + .../html/assets/sass/lbd/_cards.scss | 207 + .../html/assets/sass/lbd/_chartist.scss | 230 + .../sass/lbd/_checkbox-radio-switch.scss | 246 + .../html/assets/sass/lbd/_dropdown.scss | 120 + .../html/assets/sass/lbd/_footers.scss | 77 + .../html/assets/sass/lbd/_inputs.scss | 141 + .../html/assets/sass/lbd/_misc.scss | 62 + .../html/assets/sass/lbd/_mixins.scss | 22 + .../html/assets/sass/lbd/_navbars.scss | 293 + .../html/assets/sass/lbd/_responsive.scss | 413 + .../sass/lbd/_sidebar-and-main-panel.scss | 244 + .../html/assets/sass/lbd/_tables.scss | 57 + .../html/assets/sass/lbd/_typography.scss | 90 + .../html/assets/sass/lbd/_variables.scss | 265 + .../html/assets/sass/lbd/mixins/_buttons.scss | 70 + .../html/assets/sass/lbd/mixins/_cards.scss | 8 + .../assets/sass/lbd/mixins/_chartist.scss | 85 + .../html/assets/sass/lbd/mixins/_icons.scss | 13 + .../html/assets/sass/lbd/mixins/_inputs.scss | 17 + .../html/assets/sass/lbd/mixins/_labels.scss | 21 + .../sass/lbd/mixins/_morphing-buttons.scss | 34 + .../html/assets/sass/lbd/mixins/_navbars.scss | 11 + .../sass/lbd/mixins/_social-buttons.scss | 43 + .../html/assets/sass/lbd/mixins/_tabs.scss | 4 + .../assets/sass/lbd/mixins/_transparency.scss | 20 + .../sass/lbd/mixins/_vendor-prefixes.scss | 189 + .../sass/light-bootstrap-dashboard.scss | 23 + .../main_report/html/css/barchartstyle.css | 1 + .../html/main_report/html/css/graph.css | 1 + .../html/main_report/html/css/helptip.css | 1 + .../html/main_report/html/css/legend.css | 1 + .../html/main_report/html/css/style.css | 1 + .../html/main_report/html/css/treemap.css | 1 + .../html/main_report/html/css/vis.css | 1 + .../font-awesome-4.7.0/css/font-awesome.css | 2337 ++++ .../css/font-awesome.min.css | 4 + .../font-awesome-4.7.0/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../fonts/fontawesome-webfont.svg | 2671 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../font-awesome-4.7.0/less/animated.less | 34 + .../less/bordered-pulled.less | 25 + .../fonts/font-awesome-4.7.0/less/core.less | 12 + .../font-awesome-4.7.0/less/fixed-width.less | 6 + .../font-awesome-4.7.0/less/font-awesome.less | 18 + .../fonts/font-awesome-4.7.0/less/icons.less | 789 ++ .../fonts/font-awesome-4.7.0/less/larger.less | 13 + .../fonts/font-awesome-4.7.0/less/list.less | 19 + .../fonts/font-awesome-4.7.0/less/mixins.less | 60 + .../fonts/font-awesome-4.7.0/less/path.less | 15 + .../less/rotated-flipped.less | 20 + .../less/screen-reader.less | 5 + .../font-awesome-4.7.0/less/stacked.less | 20 + .../font-awesome-4.7.0/less/variables.less | 800 ++ .../font-awesome-4.7.0/scss/_animated.scss | 34 + .../scss/_bordered-pulled.scss | 25 + .../fonts/font-awesome-4.7.0/scss/_core.scss | 12 + .../font-awesome-4.7.0/scss/_fixed-width.scss | 6 + .../fonts/font-awesome-4.7.0/scss/_icons.scss | 789 ++ .../font-awesome-4.7.0/scss/_larger.scss | 13 + .../fonts/font-awesome-4.7.0/scss/_list.scss | 19 + .../font-awesome-4.7.0/scss/_mixins.scss | 60 + .../fonts/font-awesome-4.7.0/scss/_path.scss | 15 + .../scss/_rotated-flipped.scss | 20 + .../scss/_screen-reader.scss | 5 + .../font-awesome-4.7.0/scss/_stacked.scss | 20 + .../font-awesome-4.7.0/scss/_variables.scss | 800 ++ .../font-awesome-4.7.0/scss/font-awesome.scss | 18 + .../html/fonts/font-codemr/config.json | 24 + .../html/fonts/font-codemr/css/animation.css | 85 + .../fonts/font-codemr/css/codemr-codes.css | 2 + .../fonts/font-codemr/css/codemr-embedded.css | 55 + .../font-codemr/css/codemr-ie7-codes.css | 2 + .../html/fonts/font-codemr/css/codemr-ie7.css | 13 + .../html/fonts/font-codemr/css/codemr.css | 58 + .../html/fonts/font-codemr/demo.html | 309 + .../html/fonts/font-codemr/font/codemr.eot | Bin 0 -> 5016 bytes .../html/fonts/font-codemr/font/codemr.svg | 12 + .../html/fonts/font-codemr/font/codemr.ttf | Bin 0 -> 4856 bytes .../html/fonts/font-codemr/font/codemr.woff | Bin 0 -> 2740 bytes .../html/fonts/font-codemr/font/codemr.woff2 | Bin 0 -> 2212 bytes .../html/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes ...yrillic_latin-ext_greek-ext_greek-300.woff | Bin 0 -> 82320 bytes ...rillic_latin-ext_greek-ext_greek-300.woff2 | Bin 0 -> 63104 bytes ...yrillic_latin-ext_greek-ext_greek-700.woff | Bin 0 -> 82860 bytes ...rillic_latin-ext_greek-ext_greek-700.woff2 | Bin 0 -> 63396 bytes ...lic_latin-ext_greek-ext_greek-regular.woff | Bin 0 -> 82560 bytes ...ic_latin-ext_greek-ext_greek-regular.woff2 | Bin 0 -> 63156 bytes .../main_report/html/fonts/robotofonts.css | 28 + .../main_report/html/img/eqGraphlegend.png | Bin 0 -> 13748 bytes .../html/main_report/html/img/help.png | Bin 0 -> 239 bytes .../html/main_report/html/js/circlepack.js | 1 + .../html/main_report/html/js/d3.min.js | 1 + .../html/main_report/html/js/d3.tip.v0.6.3.js | 1 + .../main_report/html/js/dependency_wheel.js | 1 + .../html/main_report/html/js/donut3d.js | 1 + .../html/main_report/html/js/eq.js | 1 + .../main_report/html/js/metric_definitions.js | 1 + .../html/main_report/html/js/metricchart.js | 1 + .../html/main_report/html/js/sunburst.js | 1 + .../html/main_report/html/js/treemap.js | 1 + .../html/main_report/html/js/vis.js | 25 + .../main_report/html/js/vis_eq_cluster.js | 1 + .../main_report/html/js/vis_eq_graph_base.js | 1 + .../html/main_report/htmlx/Xdonut.html | 107 + .../html/main_report/htmlx/circlepack.html | 113 + .../html/main_report/htmlx/dependency.html | 31 + .../html/main_report/htmlx/donut.html | 179 + .../html/main_report/htmlx/donutcharts.html | 42 + .../main_report/htmlx/donutchartssimple.html | 26 + .../html/main_report/htmlx/lbd/README.md | 109 + .../html/main_report/htmlx/lbd/dashboard.html | 334 + .../html/main_report/htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../main_report/htmlx/lbd/notifications.html | 310 + .../html/main_report/htmlx/lbd/table.html | 446 + .../html/main_report/htmlx/lbd/template.html | 154 + .../main_report/htmlx/metricchartmethod.html | 27 + .../main_report/htmlx/metricchartpackage.html | 25 + .../html/main_report/htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 17 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 226 + .../main_report/htmlx/modeldata/table_data.js | 1 + .../html/main_report/htmlx/report.html | 28 + .../main_report/htmlx/reportforprint.html | 28 + .../html/main_report/htmlx/sunburst.html | 106 + .../html/main_report/htmlx/treemap.html | 56 + .../serialx-core/html/main_report/index.html | 1 + .../codemr/serialx-core/html/workingsets.js | 3 + .../codemr/serialx-core/serialx-core.mdl | Bin 0 -> 47867 bytes .../codemr/serialx-core/serialx-core.qa | 1 + .../codemr/serialx-core/serialx-core.ws | 1 + .../serialx-json/graphs/all_bymodularity.cmr | 1 + .../serialx-json/graphs/all_bypackage.cmr | 1 + .../graphs/all_byprojectmodule.cmr | 1 + .../codemr/serialx-json/graphs/all_nm.cmr | 1 + .../html/graph_htmls/all_bymodularity.html | 1 + .../html/graph_htmls/all_bymodularity.png | Bin 0 -> 1694 bytes .../html/graph_htmls/all_bypackage.html | 1 + .../html/graph_htmls/all_bypackage.png | Bin 0 -> 2313 bytes .../html/graph_htmls/all_byprojectmodule.html | 1 + .../html/graph_htmls/all_byprojectmodule.png | Bin 0 -> 1517 bytes .../serialx-json/html/graph_htmls/all_nm.html | 1 + .../serialx-json/html/graph_htmls/all_nm.png | Bin 0 -> 1694 bytes .../html/graph_htmls/graphlist.js | 1 + .../htmlx/Xdonut.html | 107 + .../htmlx/circlepack.html | 113 + .../htmlx/dependency.html | 31 + .../html_report_serialx-json/htmlx/donut.html | 179 + .../htmlx/donutcharts.html | 42 + .../htmlx/donutchartssimple.html | 26 + .../htmlx/lbd/README.md | 109 + .../htmlx/lbd/dashboard.html | 334 + .../htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../htmlx/lbd/notifications.html | 310 + .../htmlx/lbd/table.html | 446 + .../htmlx/lbd/template.html | 154 + .../htmlx/metricchartmethod.html | 27 + .../htmlx/metricchartpackage.html | 25 + .../htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 8 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 108 + .../htmlx/modeldata/table_data.js | 1 + .../htmlx/report.html | 28 + .../htmlx/reportforprint.html | 28 + .../htmlx/sunburst.html | 106 + .../htmlx/treemap.html | 56 + .../html/html_report_serialx-json/index.html | 1 + .../html/assets/css/animate.min.css | 6 + .../html/assets/css/bootstrap.min.css | 5 + .../html/main_report/html/assets/css/demo.css | 61 + .../html/assets/css/font-awesome.min.css | 4 + .../main_report/html/assets/css/helptip.css | 148 + .../assets/css/light-bootstrap-dashboard.css | 3393 ++++++ .../html/assets/css/pe-icon-7-stroke.css | 632 ++ .../html/assets/fonts/Pe-icon-7-stroke.eot | Bin 0 -> 58680 bytes .../html/assets/fonts/Pe-icon-7-stroke.svg | 212 + .../html/assets/fonts/Pe-icon-7-stroke.ttf | Bin 0 -> 58480 bytes .../html/assets/fonts/Pe-icon-7-stroke.woff | Bin 0 -> 58556 bytes .../html/assets/img/codemr-icon-black-1.png | Bin 0 -> 15510 bytes .../html/assets/img/codemr-white-32.png | Bin 0 -> 1254 bytes .../html/assets/img/default-avatar.png | Bin 0 -> 2864 bytes .../main_report/html/assets/img/favicon.ico | Bin 0 -> 1150 bytes .../html/assets/img/loading-bubbles.svg | 14 + .../html/main_report/html/assets/img/mask.png | Bin 0 -> 756 bytes .../main_report/html/assets/img/new_logo.png | Bin 0 -> 3557 bytes .../main_report/html/assets/img/sidebar-5.jpg | Bin 0 -> 280836 bytes .../js/bootstrap-checkbox-radio-switch.js | 502 + .../html/assets/js/bootstrap-notify.js | 404 + .../html/assets/js/bootstrap-select.js | 438 + .../html/assets/js/bootstrap.min.js | 7 + .../html/assets/js/chartist.min.js | 9 + .../html/main_report/html/assets/js/demo.js | 152 + .../html/assets/js/jquery-1.10.2.js | 9789 +++++++++++++++++ .../assets/js/light-bootstrap-dashboard.js | 159 + .../html/assets/sass/lbd/_alerts.scss | 82 + .../html/assets/sass/lbd/_buttons.scss | 108 + .../html/assets/sass/lbd/_cards.scss | 207 + .../html/assets/sass/lbd/_chartist.scss | 230 + .../sass/lbd/_checkbox-radio-switch.scss | 246 + .../html/assets/sass/lbd/_dropdown.scss | 120 + .../html/assets/sass/lbd/_footers.scss | 77 + .../html/assets/sass/lbd/_inputs.scss | 141 + .../html/assets/sass/lbd/_misc.scss | 62 + .../html/assets/sass/lbd/_mixins.scss | 22 + .../html/assets/sass/lbd/_navbars.scss | 293 + .../html/assets/sass/lbd/_responsive.scss | 413 + .../sass/lbd/_sidebar-and-main-panel.scss | 244 + .../html/assets/sass/lbd/_tables.scss | 57 + .../html/assets/sass/lbd/_typography.scss | 90 + .../html/assets/sass/lbd/_variables.scss | 265 + .../html/assets/sass/lbd/mixins/_buttons.scss | 70 + .../html/assets/sass/lbd/mixins/_cards.scss | 8 + .../assets/sass/lbd/mixins/_chartist.scss | 85 + .../html/assets/sass/lbd/mixins/_icons.scss | 13 + .../html/assets/sass/lbd/mixins/_inputs.scss | 17 + .../html/assets/sass/lbd/mixins/_labels.scss | 21 + .../sass/lbd/mixins/_morphing-buttons.scss | 34 + .../html/assets/sass/lbd/mixins/_navbars.scss | 11 + .../sass/lbd/mixins/_social-buttons.scss | 43 + .../html/assets/sass/lbd/mixins/_tabs.scss | 4 + .../assets/sass/lbd/mixins/_transparency.scss | 20 + .../sass/lbd/mixins/_vendor-prefixes.scss | 189 + .../sass/light-bootstrap-dashboard.scss | 23 + .../main_report/html/css/barchartstyle.css | 1 + .../html/main_report/html/css/graph.css | 1 + .../html/main_report/html/css/helptip.css | 1 + .../html/main_report/html/css/legend.css | 1 + .../html/main_report/html/css/style.css | 1 + .../html/main_report/html/css/treemap.css | 1 + .../html/main_report/html/css/vis.css | 1 + .../font-awesome-4.7.0/css/font-awesome.css | 2337 ++++ .../css/font-awesome.min.css | 4 + .../font-awesome-4.7.0/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../fonts/fontawesome-webfont.svg | 2671 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../font-awesome-4.7.0/less/animated.less | 34 + .../less/bordered-pulled.less | 25 + .../fonts/font-awesome-4.7.0/less/core.less | 12 + .../font-awesome-4.7.0/less/fixed-width.less | 6 + .../font-awesome-4.7.0/less/font-awesome.less | 18 + .../fonts/font-awesome-4.7.0/less/icons.less | 789 ++ .../fonts/font-awesome-4.7.0/less/larger.less | 13 + .../fonts/font-awesome-4.7.0/less/list.less | 19 + .../fonts/font-awesome-4.7.0/less/mixins.less | 60 + .../fonts/font-awesome-4.7.0/less/path.less | 15 + .../less/rotated-flipped.less | 20 + .../less/screen-reader.less | 5 + .../font-awesome-4.7.0/less/stacked.less | 20 + .../font-awesome-4.7.0/less/variables.less | 800 ++ .../font-awesome-4.7.0/scss/_animated.scss | 34 + .../scss/_bordered-pulled.scss | 25 + .../fonts/font-awesome-4.7.0/scss/_core.scss | 12 + .../font-awesome-4.7.0/scss/_fixed-width.scss | 6 + .../fonts/font-awesome-4.7.0/scss/_icons.scss | 789 ++ .../font-awesome-4.7.0/scss/_larger.scss | 13 + .../fonts/font-awesome-4.7.0/scss/_list.scss | 19 + .../font-awesome-4.7.0/scss/_mixins.scss | 60 + .../fonts/font-awesome-4.7.0/scss/_path.scss | 15 + .../scss/_rotated-flipped.scss | 20 + .../scss/_screen-reader.scss | 5 + .../font-awesome-4.7.0/scss/_stacked.scss | 20 + .../font-awesome-4.7.0/scss/_variables.scss | 800 ++ .../font-awesome-4.7.0/scss/font-awesome.scss | 18 + .../html/fonts/font-codemr/config.json | 24 + .../html/fonts/font-codemr/css/animation.css | 85 + .../fonts/font-codemr/css/codemr-codes.css | 2 + .../fonts/font-codemr/css/codemr-embedded.css | 55 + .../font-codemr/css/codemr-ie7-codes.css | 2 + .../html/fonts/font-codemr/css/codemr-ie7.css | 13 + .../html/fonts/font-codemr/css/codemr.css | 58 + .../html/fonts/font-codemr/demo.html | 309 + .../html/fonts/font-codemr/font/codemr.eot | Bin 0 -> 5016 bytes .../html/fonts/font-codemr/font/codemr.svg | 12 + .../html/fonts/font-codemr/font/codemr.ttf | Bin 0 -> 4856 bytes .../html/fonts/font-codemr/font/codemr.woff | Bin 0 -> 2740 bytes .../html/fonts/font-codemr/font/codemr.woff2 | Bin 0 -> 2212 bytes .../html/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes ...yrillic_latin-ext_greek-ext_greek-300.woff | Bin 0 -> 82320 bytes ...rillic_latin-ext_greek-ext_greek-300.woff2 | Bin 0 -> 63104 bytes ...yrillic_latin-ext_greek-ext_greek-700.woff | Bin 0 -> 82860 bytes ...rillic_latin-ext_greek-ext_greek-700.woff2 | Bin 0 -> 63396 bytes ...lic_latin-ext_greek-ext_greek-regular.woff | Bin 0 -> 82560 bytes ...ic_latin-ext_greek-ext_greek-regular.woff2 | Bin 0 -> 63156 bytes .../main_report/html/fonts/robotofonts.css | 28 + .../main_report/html/img/eqGraphlegend.png | Bin 0 -> 13748 bytes .../html/main_report/html/img/help.png | Bin 0 -> 239 bytes .../html/main_report/html/js/circlepack.js | 1 + .../html/main_report/html/js/d3.min.js | 1 + .../html/main_report/html/js/d3.tip.v0.6.3.js | 1 + .../main_report/html/js/dependency_wheel.js | 1 + .../html/main_report/html/js/donut3d.js | 1 + .../html/main_report/html/js/eq.js | 1 + .../main_report/html/js/metric_definitions.js | 1 + .../html/main_report/html/js/metricchart.js | 1 + .../html/main_report/html/js/sunburst.js | 1 + .../html/main_report/html/js/treemap.js | 1 + .../html/main_report/html/js/vis.js | 25 + .../main_report/html/js/vis_eq_cluster.js | 1 + .../main_report/html/js/vis_eq_graph_base.js | 1 + .../html/main_report/htmlx/Xdonut.html | 107 + .../html/main_report/htmlx/circlepack.html | 113 + .../html/main_report/htmlx/dependency.html | 31 + .../html/main_report/htmlx/donut.html | 179 + .../html/main_report/htmlx/donutcharts.html | 42 + .../main_report/htmlx/donutchartssimple.html | 26 + .../html/main_report/htmlx/lbd/README.md | 109 + .../html/main_report/htmlx/lbd/dashboard.html | 334 + .../html/main_report/htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../main_report/htmlx/lbd/notifications.html | 310 + .../html/main_report/htmlx/lbd/table.html | 446 + .../html/main_report/htmlx/lbd/template.html | 154 + .../main_report/htmlx/metricchartmethod.html | 27 + .../main_report/htmlx/metricchartpackage.html | 25 + .../html/main_report/htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 8 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 108 + .../main_report/htmlx/modeldata/table_data.js | 1 + .../html/main_report/htmlx/report.html | 28 + .../main_report/htmlx/reportforprint.html | 28 + .../html/main_report/htmlx/sunburst.html | 106 + .../html/main_report/htmlx/treemap.html | 56 + .../serialx-json/html/main_report/index.html | 1 + .../codemr/serialx-json/html/workingsets.js | 3 + .../codemr/serialx-json/serialx-json.mdl | Bin 0 -> 20668 bytes .../codemr/serialx-json/serialx-json.qa | 1 + .../codemr/serialx-json/serialx-json.ws | 1 + .../serialx-juss/graphs/all_bymodularity.cmr | 1 + .../serialx-juss/graphs/all_bypackage.cmr | 1 + .../graphs/all_byprojectmodule.cmr | 1 + .../codemr/serialx-juss/graphs/all_nm.cmr | 1 + .../graphs/all_nm_inheritance.cmr | 1 + .../html/graph_htmls/all_bymodularity.html | 1 + .../html/graph_htmls/all_bymodularity.png | Bin 0 -> 2664 bytes .../html/graph_htmls/all_bypackage.html | 1 + .../html/graph_htmls/all_bypackage.png | Bin 0 -> 3448 bytes .../html/graph_htmls/all_byprojectmodule.html | 1 + .../html/graph_htmls/all_byprojectmodule.png | Bin 0 -> 2323 bytes .../serialx-juss/html/graph_htmls/all_nm.html | 1 + .../serialx-juss/html/graph_htmls/all_nm.png | Bin 0 -> 2664 bytes .../html/graph_htmls/all_nm_inheritance.html | 1 + .../html/graph_htmls/all_nm_inheritance.png | Bin 0 -> 1402 bytes .../html/graph_htmls/graphlist.js | 1 + .../htmlx/Xdonut.html | 107 + .../htmlx/circlepack.html | 113 + .../htmlx/dependency.html | 31 + .../html_report_serialx-juss/htmlx/donut.html | 179 + .../htmlx/donutcharts.html | 42 + .../htmlx/donutchartssimple.html | 26 + .../htmlx/lbd/README.md | 109 + .../htmlx/lbd/dashboard.html | 334 + .../htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../htmlx/lbd/notifications.html | 310 + .../htmlx/lbd/table.html | 446 + .../htmlx/lbd/template.html | 154 + .../htmlx/metricchartmethod.html | 27 + .../htmlx/metricchartpackage.html | 25 + .../htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 11 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 139 + .../htmlx/modeldata/table_data.js | 1 + .../htmlx/report.html | 28 + .../htmlx/reportforprint.html | 28 + .../htmlx/sunburst.html | 106 + .../htmlx/treemap.html | 56 + .../html/html_report_serialx-juss/index.html | 1 + .../html/assets/css/animate.min.css | 6 + .../html/assets/css/bootstrap.min.css | 5 + .../html/main_report/html/assets/css/demo.css | 61 + .../html/assets/css/font-awesome.min.css | 4 + .../main_report/html/assets/css/helptip.css | 148 + .../assets/css/light-bootstrap-dashboard.css | 3393 ++++++ .../html/assets/css/pe-icon-7-stroke.css | 632 ++ .../html/assets/fonts/Pe-icon-7-stroke.eot | Bin 0 -> 58680 bytes .../html/assets/fonts/Pe-icon-7-stroke.svg | 212 + .../html/assets/fonts/Pe-icon-7-stroke.ttf | Bin 0 -> 58480 bytes .../html/assets/fonts/Pe-icon-7-stroke.woff | Bin 0 -> 58556 bytes .../html/assets/img/codemr-icon-black-1.png | Bin 0 -> 15510 bytes .../html/assets/img/codemr-white-32.png | Bin 0 -> 1254 bytes .../html/assets/img/default-avatar.png | Bin 0 -> 2864 bytes .../main_report/html/assets/img/favicon.ico | Bin 0 -> 1150 bytes .../html/assets/img/loading-bubbles.svg | 14 + .../html/main_report/html/assets/img/mask.png | Bin 0 -> 756 bytes .../main_report/html/assets/img/new_logo.png | Bin 0 -> 3557 bytes .../main_report/html/assets/img/sidebar-5.jpg | Bin 0 -> 280836 bytes .../js/bootstrap-checkbox-radio-switch.js | 502 + .../html/assets/js/bootstrap-notify.js | 404 + .../html/assets/js/bootstrap-select.js | 438 + .../html/assets/js/bootstrap.min.js | 7 + .../html/assets/js/chartist.min.js | 9 + .../html/main_report/html/assets/js/demo.js | 152 + .../html/assets/js/jquery-1.10.2.js | 9789 +++++++++++++++++ .../assets/js/light-bootstrap-dashboard.js | 159 + .../html/assets/sass/lbd/_alerts.scss | 82 + .../html/assets/sass/lbd/_buttons.scss | 108 + .../html/assets/sass/lbd/_cards.scss | 207 + .../html/assets/sass/lbd/_chartist.scss | 230 + .../sass/lbd/_checkbox-radio-switch.scss | 246 + .../html/assets/sass/lbd/_dropdown.scss | 120 + .../html/assets/sass/lbd/_footers.scss | 77 + .../html/assets/sass/lbd/_inputs.scss | 141 + .../html/assets/sass/lbd/_misc.scss | 62 + .../html/assets/sass/lbd/_mixins.scss | 22 + .../html/assets/sass/lbd/_navbars.scss | 293 + .../html/assets/sass/lbd/_responsive.scss | 413 + .../sass/lbd/_sidebar-and-main-panel.scss | 244 + .../html/assets/sass/lbd/_tables.scss | 57 + .../html/assets/sass/lbd/_typography.scss | 90 + .../html/assets/sass/lbd/_variables.scss | 265 + .../html/assets/sass/lbd/mixins/_buttons.scss | 70 + .../html/assets/sass/lbd/mixins/_cards.scss | 8 + .../assets/sass/lbd/mixins/_chartist.scss | 85 + .../html/assets/sass/lbd/mixins/_icons.scss | 13 + .../html/assets/sass/lbd/mixins/_inputs.scss | 17 + .../html/assets/sass/lbd/mixins/_labels.scss | 21 + .../sass/lbd/mixins/_morphing-buttons.scss | 34 + .../html/assets/sass/lbd/mixins/_navbars.scss | 11 + .../sass/lbd/mixins/_social-buttons.scss | 43 + .../html/assets/sass/lbd/mixins/_tabs.scss | 4 + .../assets/sass/lbd/mixins/_transparency.scss | 20 + .../sass/lbd/mixins/_vendor-prefixes.scss | 189 + .../sass/light-bootstrap-dashboard.scss | 23 + .../main_report/html/css/barchartstyle.css | 1 + .../html/main_report/html/css/graph.css | 1 + .../html/main_report/html/css/helptip.css | 1 + .../html/main_report/html/css/legend.css | 1 + .../html/main_report/html/css/style.css | 1 + .../html/main_report/html/css/treemap.css | 1 + .../html/main_report/html/css/vis.css | 1 + .../font-awesome-4.7.0/css/font-awesome.css | 2337 ++++ .../css/font-awesome.min.css | 4 + .../font-awesome-4.7.0/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../fonts/fontawesome-webfont.svg | 2671 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../font-awesome-4.7.0/less/animated.less | 34 + .../less/bordered-pulled.less | 25 + .../fonts/font-awesome-4.7.0/less/core.less | 12 + .../font-awesome-4.7.0/less/fixed-width.less | 6 + .../font-awesome-4.7.0/less/font-awesome.less | 18 + .../fonts/font-awesome-4.7.0/less/icons.less | 789 ++ .../fonts/font-awesome-4.7.0/less/larger.less | 13 + .../fonts/font-awesome-4.7.0/less/list.less | 19 + .../fonts/font-awesome-4.7.0/less/mixins.less | 60 + .../fonts/font-awesome-4.7.0/less/path.less | 15 + .../less/rotated-flipped.less | 20 + .../less/screen-reader.less | 5 + .../font-awesome-4.7.0/less/stacked.less | 20 + .../font-awesome-4.7.0/less/variables.less | 800 ++ .../font-awesome-4.7.0/scss/_animated.scss | 34 + .../scss/_bordered-pulled.scss | 25 + .../fonts/font-awesome-4.7.0/scss/_core.scss | 12 + .../font-awesome-4.7.0/scss/_fixed-width.scss | 6 + .../fonts/font-awesome-4.7.0/scss/_icons.scss | 789 ++ .../font-awesome-4.7.0/scss/_larger.scss | 13 + .../fonts/font-awesome-4.7.0/scss/_list.scss | 19 + .../font-awesome-4.7.0/scss/_mixins.scss | 60 + .../fonts/font-awesome-4.7.0/scss/_path.scss | 15 + .../scss/_rotated-flipped.scss | 20 + .../scss/_screen-reader.scss | 5 + .../font-awesome-4.7.0/scss/_stacked.scss | 20 + .../font-awesome-4.7.0/scss/_variables.scss | 800 ++ .../font-awesome-4.7.0/scss/font-awesome.scss | 18 + .../html/fonts/font-codemr/config.json | 24 + .../html/fonts/font-codemr/css/animation.css | 85 + .../fonts/font-codemr/css/codemr-codes.css | 2 + .../fonts/font-codemr/css/codemr-embedded.css | 55 + .../font-codemr/css/codemr-ie7-codes.css | 2 + .../html/fonts/font-codemr/css/codemr-ie7.css | 13 + .../html/fonts/font-codemr/css/codemr.css | 58 + .../html/fonts/font-codemr/demo.html | 309 + .../html/fonts/font-codemr/font/codemr.eot | Bin 0 -> 5016 bytes .../html/fonts/font-codemr/font/codemr.svg | 12 + .../html/fonts/font-codemr/font/codemr.ttf | Bin 0 -> 4856 bytes .../html/fonts/font-codemr/font/codemr.woff | Bin 0 -> 2740 bytes .../html/fonts/font-codemr/font/codemr.woff2 | Bin 0 -> 2212 bytes .../html/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes ...yrillic_latin-ext_greek-ext_greek-300.woff | Bin 0 -> 82320 bytes ...rillic_latin-ext_greek-ext_greek-300.woff2 | Bin 0 -> 63104 bytes ...yrillic_latin-ext_greek-ext_greek-700.woff | Bin 0 -> 82860 bytes ...rillic_latin-ext_greek-ext_greek-700.woff2 | Bin 0 -> 63396 bytes ...lic_latin-ext_greek-ext_greek-regular.woff | Bin 0 -> 82560 bytes ...ic_latin-ext_greek-ext_greek-regular.woff2 | Bin 0 -> 63156 bytes .../main_report/html/fonts/robotofonts.css | 28 + .../main_report/html/img/eqGraphlegend.png | Bin 0 -> 13748 bytes .../html/main_report/html/img/help.png | Bin 0 -> 239 bytes .../html/main_report/html/js/circlepack.js | 1 + .../html/main_report/html/js/d3.min.js | 1 + .../html/main_report/html/js/d3.tip.v0.6.3.js | 1 + .../main_report/html/js/dependency_wheel.js | 1 + .../html/main_report/html/js/donut3d.js | 1 + .../html/main_report/html/js/eq.js | 1 + .../main_report/html/js/metric_definitions.js | 1 + .../html/main_report/html/js/metricchart.js | 1 + .../html/main_report/html/js/sunburst.js | 1 + .../html/main_report/html/js/treemap.js | 1 + .../html/main_report/html/js/vis.js | 25 + .../main_report/html/js/vis_eq_cluster.js | 1 + .../main_report/html/js/vis_eq_graph_base.js | 1 + .../html/main_report/htmlx/Xdonut.html | 107 + .../html/main_report/htmlx/circlepack.html | 113 + .../html/main_report/htmlx/dependency.html | 31 + .../html/main_report/htmlx/donut.html | 179 + .../html/main_report/htmlx/donutcharts.html | 42 + .../main_report/htmlx/donutchartssimple.html | 26 + .../html/main_report/htmlx/lbd/README.md | 109 + .../html/main_report/htmlx/lbd/dashboard.html | 334 + .../html/main_report/htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../main_report/htmlx/lbd/notifications.html | 310 + .../html/main_report/htmlx/lbd/table.html | 446 + .../html/main_report/htmlx/lbd/template.html | 154 + .../main_report/htmlx/metricchartmethod.html | 27 + .../main_report/htmlx/metricchartpackage.html | 25 + .../html/main_report/htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 11 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 139 + .../main_report/htmlx/modeldata/table_data.js | 1 + .../html/main_report/htmlx/report.html | 28 + .../main_report/htmlx/reportforprint.html | 28 + .../html/main_report/htmlx/sunburst.html | 106 + .../html/main_report/htmlx/treemap.html | 56 + .../serialx-juss/html/main_report/index.html | 1 + .../codemr/serialx-juss/html/workingsets.js | 3 + .../codemr/serialx-juss/serialx-juss.mdl | Bin 0 -> 27483 bytes .../codemr/serialx-juss/serialx-juss.qa | 1 + .../codemr/serialx-juss/serialx-juss.ws | 1 + 624 files changed, 103238 insertions(+) create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_nm.cmr create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/graphlist.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/Xdonut.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/circlepack.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/dependency.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donut.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutcharts.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutchartssimple.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/README.md create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/dashboard.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/graphs.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/notifications.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/table.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/template.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartmethod.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartpackage.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartx.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/summary_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/table_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/report.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/reportforprint.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/sunburst.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/treemap.html create mode 100644 SerialX-core/codemr/serialx-core/html/html_report_serialx-core/index.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/animate.min.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/bootstrap.min.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/demo.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/font-awesome.min.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/helptip.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/light-bootstrap-dashboard.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/pe-icon-7-stroke.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-icon-black-1.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-white-32.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/default-avatar.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/favicon.ico create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/loading-bubbles.svg create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/mask.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/new_logo.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/sidebar-5.jpg create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-notify.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-select.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap.min.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/chartist.min.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/demo.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/jquery-1.10.2.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/light-bootstrap-dashboard.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_alerts.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_buttons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_cards.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_chartist.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_checkbox-radio-switch.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_dropdown.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_footers.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_inputs.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_misc.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_mixins.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_navbars.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_responsive.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_sidebar-and-main-panel.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_tables.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_typography.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/_variables.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_buttons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_cards.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_chartist.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_icons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_inputs.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_labels.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_morphing-buttons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_navbars.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_social-buttons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_tabs.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_transparency.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/lbd/mixins/_vendor-prefixes.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/assets/sass/light-bootstrap-dashboard.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/barchartstyle.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/graph.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/helptip.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/legend.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/style.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/treemap.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/css/vis.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.min.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.svg create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/animated.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/bordered-pulled.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/core.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/fixed-width.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/font-awesome.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/icons.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/larger.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/list.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/mixins.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/path.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/rotated-flipped.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/screen-reader.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/stacked.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/less/variables.less create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_animated.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_bordered-pulled.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_core.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_fixed-width.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_icons.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_larger.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_list.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_mixins.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_path.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_rotated-flipped.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_screen-reader.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_stacked.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/_variables.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-awesome-4.7.0/scss/font-awesome.scss create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/config.json create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/animation.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/codemr-codes.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/codemr-embedded.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/codemr-ie7-codes.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/codemr-ie7.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/css/codemr.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/demo.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/font/codemr.eot create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/font/codemr.svg create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/font/codemr.ttf create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/font/codemr.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/font-codemr/font/codemr.woff2 create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/fontawesome-webfont.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff2 create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff2 create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff2 create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/fonts/robotofonts.css create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/img/eqGraphlegend.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/img/help.png create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/circlepack.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/d3.min.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/d3.tip.v0.6.3.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/dependency_wheel.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/donut3d.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/eq.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/metric_definitions.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/metricchart.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/sunburst.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/treemap.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/vis.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/vis_eq_cluster.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/html/js/vis_eq_graph_base.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/Xdonut.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/circlepack.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/dependency.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/donut.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/donutcharts.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/donutchartssimple.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/README.md create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/dashboard.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/graphs.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/notifications.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/table.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/template.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartmethod.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartpackage.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartx.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/summary_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/table_data.js create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/report.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/reportforprint.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/sunburst.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/htmlx/treemap.html create mode 100644 SerialX-core/codemr/serialx-core/html/main_report/index.html create mode 100644 SerialX-core/codemr/serialx-core/html/workingsets.js create mode 100644 SerialX-core/codemr/serialx-core/serialx-core.mdl create mode 100644 SerialX-core/codemr/serialx-core/serialx-core.qa create mode 100644 SerialX-core/codemr/serialx-core/serialx-core.ws create mode 100644 SerialX-json/codemr/serialx-json/graphs/all_bymodularity.cmr create mode 100644 SerialX-json/codemr/serialx-json/graphs/all_bypackage.cmr create mode 100644 SerialX-json/codemr/serialx-json/graphs/all_byprojectmodule.cmr create mode 100644 SerialX-json/codemr/serialx-json/graphs/all_nm.cmr create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.html create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.png create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.html create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.png create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.html create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.png create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.html create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.png create mode 100644 SerialX-json/codemr/serialx-json/html/graph_htmls/graphlist.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/Xdonut.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/circlepack.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/dependency.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donut.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutcharts.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutchartssimple.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/README.md create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/dashboard.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/graphs.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/notifications.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/table.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/template.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartmethod.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartpackage.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartx.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/summary_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/table_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/report.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/reportforprint.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/sunburst.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/treemap.html create mode 100644 SerialX-json/codemr/serialx-json/html/html_report_serialx-json/index.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/animate.min.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/bootstrap.min.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/demo.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/font-awesome.min.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/helptip.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/light-bootstrap-dashboard.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/pe-icon-7-stroke.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-icon-black-1.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-white-32.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/default-avatar.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/favicon.ico create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/loading-bubbles.svg create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/mask.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/new_logo.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/sidebar-5.jpg create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-notify.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-select.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap.min.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/chartist.min.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/demo.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/jquery-1.10.2.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/light-bootstrap-dashboard.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_alerts.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_buttons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_cards.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_chartist.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_checkbox-radio-switch.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_dropdown.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_footers.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_inputs.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_misc.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_mixins.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_navbars.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_responsive.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_sidebar-and-main-panel.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_tables.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_typography.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/_variables.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_buttons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_cards.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_chartist.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_icons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_inputs.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_labels.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_morphing-buttons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_navbars.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_social-buttons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_tabs.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_transparency.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/lbd/mixins/_vendor-prefixes.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/assets/sass/light-bootstrap-dashboard.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/barchartstyle.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/graph.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/helptip.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/legend.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/style.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/treemap.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/css/vis.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.min.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.svg create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/animated.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/bordered-pulled.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/core.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/fixed-width.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/font-awesome.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/icons.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/larger.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/list.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/mixins.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/path.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/rotated-flipped.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/screen-reader.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/stacked.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/less/variables.less create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_animated.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_bordered-pulled.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_core.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_fixed-width.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_icons.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_larger.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_list.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_mixins.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_path.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_rotated-flipped.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_screen-reader.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_stacked.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/_variables.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-awesome-4.7.0/scss/font-awesome.scss create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/config.json create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/animation.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/codemr-codes.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/codemr-embedded.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/codemr-ie7-codes.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/codemr-ie7.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/css/codemr.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/demo.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/font/codemr.eot create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/font/codemr.svg create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/font/codemr.ttf create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/font/codemr.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/font-codemr/font/codemr.woff2 create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/fontawesome-webfont.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff2 create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff2 create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff2 create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/fonts/robotofonts.css create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/img/eqGraphlegend.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/img/help.png create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/circlepack.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/d3.min.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/d3.tip.v0.6.3.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/dependency_wheel.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/donut3d.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/eq.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/metric_definitions.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/metricchart.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/sunburst.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/treemap.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/vis.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/vis_eq_cluster.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/html/js/vis_eq_graph_base.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/Xdonut.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/circlepack.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/dependency.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/donut.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/donutcharts.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/donutchartssimple.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/README.md create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/dashboard.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/graphs.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/notifications.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/table.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/template.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartmethod.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartpackage.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartx.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/summary_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/table_data.js create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/report.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/reportforprint.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/sunburst.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/htmlx/treemap.html create mode 100644 SerialX-json/codemr/serialx-json/html/main_report/index.html create mode 100644 SerialX-json/codemr/serialx-json/html/workingsets.js create mode 100644 SerialX-json/codemr/serialx-json/serialx-json.mdl create mode 100644 SerialX-json/codemr/serialx-json/serialx-json.qa create mode 100644 SerialX-json/codemr/serialx-json/serialx-json.ws create mode 100644 SerialX-juss/codemr/serialx-juss/graphs/all_bymodularity.cmr create mode 100644 SerialX-juss/codemr/serialx-juss/graphs/all_bypackage.cmr create mode 100644 SerialX-juss/codemr/serialx-juss/graphs/all_byprojectmodule.cmr create mode 100644 SerialX-juss/codemr/serialx-juss/graphs/all_nm.cmr create mode 100644 SerialX-juss/codemr/serialx-juss/graphs/all_nm_inheritance.cmr create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/graph_htmls/graphlist.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/Xdonut.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/circlepack.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/dependency.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donut.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutcharts.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutchartssimple.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/README.md create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/dashboard.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/graphs.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/notifications.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/table.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/template.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartmethod.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartpackage.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartx.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/summary_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/table_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/report.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/reportforprint.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/sunburst.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/treemap.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/index.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/animate.min.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/bootstrap.min.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/demo.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/font-awesome.min.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/helptip.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/light-bootstrap-dashboard.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/pe-icon-7-stroke.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-icon-black-1.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-white-32.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/default-avatar.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/favicon.ico create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/loading-bubbles.svg create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/mask.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/new_logo.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/sidebar-5.jpg create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-notify.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-select.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap.min.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/chartist.min.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/demo.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/jquery-1.10.2.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/light-bootstrap-dashboard.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_alerts.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_buttons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_cards.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_chartist.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_checkbox-radio-switch.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_dropdown.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_footers.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_inputs.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_misc.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_mixins.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_navbars.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_responsive.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_sidebar-and-main-panel.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_tables.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_typography.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/_variables.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_buttons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_cards.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_chartist.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_icons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_inputs.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_labels.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_morphing-buttons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_navbars.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_social-buttons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_tabs.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_transparency.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/lbd/mixins/_vendor-prefixes.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/sass/light-bootstrap-dashboard.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/barchartstyle.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/graph.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/helptip.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/legend.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/style.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/treemap.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/css/vis.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.min.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.svg create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/animated.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/bordered-pulled.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/core.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/fixed-width.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/font-awesome.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/icons.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/larger.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/list.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/mixins.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/path.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/rotated-flipped.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/screen-reader.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/stacked.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/less/variables.less create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_animated.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_bordered-pulled.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_core.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_fixed-width.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_icons.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_larger.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_list.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_mixins.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_path.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_rotated-flipped.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_screen-reader.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_stacked.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/_variables.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-awesome-4.7.0/scss/font-awesome.scss create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/config.json create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/animation.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/codemr-codes.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/codemr-embedded.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/codemr-ie7-codes.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/codemr-ie7.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/css/codemr.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/demo.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/font/codemr.eot create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/font/codemr.svg create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/font/codemr.ttf create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/font/codemr.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/font-codemr/font/codemr.woff2 create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/fontawesome-webfont.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff2 create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff2 create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff2 create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/fonts/robotofonts.css create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/img/eqGraphlegend.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/img/help.png create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/circlepack.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/d3.min.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/d3.tip.v0.6.3.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/dependency_wheel.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/donut3d.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/eq.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/metric_definitions.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/metricchart.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/sunburst.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/treemap.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/vis.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/vis_eq_cluster.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/html/js/vis_eq_graph_base.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/Xdonut.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/circlepack.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/dependency.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donut.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donutcharts.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donutchartssimple.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/README.md create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/dashboard.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/graphs.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/notifications.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/table.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/template.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartmethod.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartpackage.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartx.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/summary_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/table_data.js create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/report.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/reportforprint.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/sunburst.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/treemap.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/main_report/index.html create mode 100644 SerialX-juss/codemr/serialx-juss/html/workingsets.js create mode 100644 SerialX-juss/codemr/serialx-juss/serialx-juss.mdl create mode 100644 SerialX-juss/codemr/serialx-juss/serialx-juss.qa create mode 100644 SerialX-juss/codemr/serialx-juss/serialx-juss.ws diff --git a/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr b/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr new file mode 100644 index 0000000..c613da6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":388.0,"y":128.0},"B":{"x":1015.0,"y":356.0},"C":{"x":213.0,"y":114.0},"D":{"x":411.0,"y":1086.0},"E":{"x":194.0,"y":297.0},"G":{"x":236.0,"y":434.0},"H":{"x":809.0,"y":633.0},"I":{"x":1144.0,"y":411.0},"J":{"x":296.0,"y":988.0},"K":{"x":338.0,"y":140.0},"L":{"x":210.0,"y":442.0},"M":{"x":335.0,"y":1205.0},"N":{"x":253.0,"y":143.0},"O":{"x":50.0,"y":327.0},"P":{"x":358.0,"y":489.0},"Q":{"x":276.0,"y":401.0},"k":{"x":257.0,"y":894.0},"m":{"x":386.0,"y":306.0},"o":{"x":930.0,"y":627.0},"r":{"x":284.0,"y":192.0},"s":{"x":496.0,"y":968.0},"t":{"x":293.0,"y":50.0},"w":{"x":555.0,"y":1169.0},"x":{"x":305.0,"y":366.0},"y":{"x":964.0,"y":488.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]}],"clusterMap":{"A":3,"B":4,"C":3,"D":2,"E":1,"G":1,"H":4,"I":4,"J":2,"K":3,"L":1,"M":2,"N":3,"O":1,"P":1,"Q":1,"k":2,"m":1,"o":4,"r":3,"s":2,"t":3,"w":2,"x":1,"y":4}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr b/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr new file mode 100644 index 0000000..4771ba4 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":527.0,"y":50.0},"B":{"x":858.0,"y":227.0},"C":{"x":421.0,"y":184.0},"D":{"x":801.0,"y":326.0},"E":{"x":716.0,"y":152.0},"G":{"x":765.0,"y":260.0},"H":{"x":988.0,"y":782.0},"I":{"x":825.0,"y":1060.0},"J":{"x":50.0,"y":730.0},"K":{"x":506.0,"y":113.0},"L":{"x":708.0,"y":293.0},"M":{"x":238.0,"y":879.0},"N":{"x":340.0,"y":157.0},"O":{"x":867.0,"y":1189.0},"P":{"x":831.0,"y":366.0},"Q":{"x":740.0,"y":283.0},"k":{"x":149.0,"y":691.0},"m":{"x":860.0,"y":191.0},"o":{"x":873.0,"y":748.0},"r":{"x":521.0,"y":172.0},"s":{"x":250.0,"y":657.0},"t":{"x":410.0,"y":83.0},"w":{"x":755.0,"y":1270.0},"x":{"x":670.0,"y":310.0},"y":{"x":928.0,"y":182.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]}],"clusterMap":{"A":2,"B":1,"C":2,"D":1,"E":1,"G":1,"H":5,"I":4,"J":3,"K":2,"L":1,"M":3,"N":2,"O":4,"P":1,"Q":1,"k":3,"m":1,"o":5,"r":2,"s":3,"t":2,"w":4,"x":1,"y":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr b/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr new file mode 100644 index 0000000..551c10e --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":353.0,"y":175.0},"B":{"x":362.0,"y":237.0},"C":{"x":411.0,"y":104.0},"D":{"x":304.0,"y":300.0},"E":{"x":324.0,"y":115.0},"G":{"x":293.0,"y":245.0},"H":{"x":695.0,"y":326.0},"I":{"x":236.0,"y":268.0},"J":{"x":153.0,"y":275.0},"K":{"x":248.0,"y":163.0},"L":{"x":325.0,"y":255.0},"M":{"x":472.0,"y":260.0},"N":{"x":285.0,"y":151.0},"O":{"x":172.0,"y":125.0},"P":{"x":359.0,"y":379.0},"Q":{"x":420.0,"y":237.0},"k":{"x":50.0,"y":275.0},"m":{"x":279.0,"y":276.0},"o":{"x":620.0,"y":229.0},"r":{"x":326.0,"y":171.0},"s":{"x":398.0,"y":157.0},"t":{"x":297.0,"y":50.0},"w":{"x":399.0,"y":403.0},"x":{"x":402.0,"y":266.0},"y":{"x":467.0,"y":202.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"H":1,"I":1,"J":1,"K":1,"L":1,"M":1,"N":1,"O":1,"P":1,"Q":1,"k":1,"m":1,"o":1,"r":1,"s":1,"t":1,"w":1,"x":1,"y":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr new file mode 100644 index 0000000..e1fcf86 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":190.0,"y":356.0},"B":{"x":615.0,"y":311.0},"C":{"x":524.0,"y":240.0},"D":{"x":249.0,"y":329.0},"E":{"x":460.0,"y":97.0},"G":{"x":337.0,"y":300.0},"H":{"x":746.0,"y":696.0},"I":{"x":649.0,"y":576.0},"J":{"x":50.0,"y":259.0},"K":{"x":566.0,"y":601.0},"L":{"x":605.0,"y":287.0},"M":{"x":200.0,"y":595.0},"N":{"x":201.0,"y":463.0},"O":{"x":274.0,"y":228.0},"P":{"x":467.0,"y":497.0},"Q":{"x":627.0,"y":289.0},"k":{"x":120.0,"y":50.0},"m":{"x":289.0,"y":283.0},"o":{"x":869.0,"y":489.0},"r":{"x":429.0,"y":702.0},"s":{"x":429.0,"y":186.0},"t":{"x":420.0,"y":435.0},"w":{"x":436.0,"y":486.0},"x":{"x":644.0,"y":312.0},"y":{"x":708.0,"y":283.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr new file mode 100644 index 0000000..b081b12 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":21},{"@type":"int","id":"#edges","v":20},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":434.0,"y":192.0},"B":{"x":596.0,"y":430.0},"C":{"x":434.0,"y":276.0},"D":{"x":434.0,"y":524.0},"E":{"x":252.0,"y":503.0},"G":{"x":596.0,"y":472.0},"J":{"x":434.0,"y":50.0},"k":{"x":596.0,"y":50.0},"K":{"x":434.0,"y":360.0},"L":{"x":596.0,"y":638.0},"M":{"x":50.0,"y":50.0},"m":{"x":596.0,"y":378.0},"N":{"x":434.0,"y":318.0},"O":{"x":50.0,"y":390.0},"P":{"x":434.0,"y":482.0},"Q":{"x":596.0,"y":326.0},"r":{"x":434.0,"y":234.0},"s":{"x":252.0,"y":50.0},"t":{"x":252.0,"y":276.0},"x":{"x":596.0,"y":524.0},"y":{"x":596.0,"y":586.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"k"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html new file mode 100644 index 0000000..7f3bed7 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html @@ -0,0 +1 @@ +CodeMR Software Graph
\ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e3e538261db4f1c477100f592221bd55eecd85 GIT binary patch literal 25490 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î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 V`Vr?0_^pi>%JS-R4Km=c{|EM?z={9> literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html new file mode 100644 index 0000000..7c5cd99 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html @@ -0,0 +1 @@ +CodeMR Software Graph
\ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png new file mode 100644 index 0000000000000000000000000000000000000000..37e491fd3f78adc8efb8cdb2054ff0c252fc06bb GIT binary patch literal 32694 zcmbqa<98*^*PYn5jfrhe>|`d+L=)S_4JNiZ!Axx1wta&e+xG81U*3P<{m|WOb+7I^ z)m3$BpMCa;P*s*eK_o={^5qMPoUG*cFJB|9vwAJ=raWgu&%fsW@wM@j<$e7|Cqa5shsHFGR)am9w72aVH(}Gok+XqNBq` zn&bW7-NIPIg#Wwev2kb#QEl0kDl~2E1cF}?w;1`sW8m|7+*h7M{|-XgzZ_ch@z}sK zym&)-h7B7Gqyp8axmExg&I^AGiVFEXonkF|prDa1s<(3gd^vnka41PXf!+H4o)1UV zO{j>P=-{qR%m*nl9$&cq5fl-rr$Y9!ws)Ny>uxVQ=r`~+Z+kea%LCAFHl9@_wCBxI zIuLq@MZ9JR&Ua z1QWgiG~E{p^CyfBKyHP=^mmNpqg4vwfe@!2?nyV!E{%xKj*H{1wxAhkB! z@^}kL42Ju)$p5AT-XyXh4 z*8TigIL*E6XDpf;ZjL=TSI6S&`9^HGlT#dM4}!tQ3TQGtQBehypRe<2vwykcmYKV+ zfIxH2LsXc%WL}Anwd)ffWwN$kHv_D9;fyq;^oW+)3HvSBWM>{yR1chrWjhn3%)-PF ztOBTRslHFoCPcvbnw>OPWt8=qTVZdP`QUQI>#nRnR?zv88nrVFFnrYJI zyy^46?%)qGKK#C28k2+)&i8g~@X+F~&NY1AR{K6G*!W+?q4`0}J=!sfc=aY3ejMkB z((X|USafV}*QQ#0j}SZ1D+Z4sXmLJ7D_7v9bM_(ac)q7M73CHA{ZN$+`lEhlK$KM+ zY#wE(@1oJyZM0_5^GHv7;kKL8EPwy!(AEY}jHD!)u^Wv;bG1n+JTTb!%I@OVam zAc`_~%aV78Yrh1@R_pn3Q{Ag7!)tda^6{;8`+I}CXvTuiY=mT=FbMLsg1`oORK-;r z8a&|G0SRy2+yGu|%OgVB&*j_?3x(~KPT|1i6!&J{=Du>k#_jRw9MS#l&%yyBx8%LO zQN!5fO_@}^eCn`QBwCfXoz0{lttL`+hhn(|Z8Mqnxe__z9vtlZqk>FKU{{diT5x(7 z_=!&{1Pch>(%oWT-^|*)jPdO*t8Z>bL;P%eml3jZ!UGJk|$ zxAO9I`HNjbuD3|Kw=;i(~yg8qR5MU~q>wP94f$MyeS$AAw~^OYWOIGS8a*Og@NlU3(sh=b5bVKmD4#F{!DS|D8zO?n#zB0LIS%P3C^A1hV?s`dt|qCA zAj^?9jBdf>oz$CDJ^^sXztPNQc^Xp<@8l-9Q@{%juo9cd5$Bb+LwcmZcCCBU20K9m z<1#!?%X3pEk$DIazN5I`*ZXi~?C8Q0cOa!FQT_s&6WA~4>6+dz^oYU_eWuVIu#@bqR_p>{vBf6HwO2oN7y zyW?{aA|39$D~z(0^y{0}(RsTeY9$yHdFWfz%R-C4G~5CII<$&~^5X=ee{@9BSBXNe7FPl_knsFLfK2G3Hu4NupZaI8;rnPfc~ zds%55U~`CLy#p6!%_o9tY$HX z%}xQ{THBGFR{1GZptpHqhSu)wIxx5h+HE}`izRItknh|y3cZakiDLWv^{UhetI)iV zc)W8M01gPozQl`{>MfiT`NDuBU%ejVTY{0FeP0QWG zn#%5VM6(7UoFMn;p*VM)1FJPK9y{eBmpiHylrV+zQRXI@4__6{iJZ* zYuYy@mGSoJ<-idAa#73dNC)Mvhz%c}sdB;}{M`vGW>IoY_?~O^@~)XQqv6?Fe>AJW zUVyp%xtt=5NN0EU3K>6^kJwNukkGBzu9g+V*0SSQCtdPvy9?<^pzC77sMaNT7KbnKpWoLJb^$!UmK0!+< zYK!M&rg4zfKMjJJrpN-gY!zaN!;Im~ZUv;L(IqmhV&MjN4$Q2Gb+*7v$v7j5@KPg5 zfjJVs7mK=NB;8({#Mp-%5zptEa&*?8&dF#CpBsiEvW%&GA~$^+jX4kP-oXHmy2oac z&HGJDkDsAF7mv^J>9gDHLe^_(nm91tQ$uCZ^x2_jw|y+X-J!EBbo=P+%Rk_&Hn%kN zW$yyp^^f1_%qe*lA7H4ffp*-|@+vS?-<7^0#qkyFt(5MN#c+!*Vl#Dt=ZNTn@7Yw_ z^!brKk4#k3LHKm{jj(R*)AfOj=*O*}huh$OndM(DVz^^kjYfKGz#x|XVGJ%bHG)C~ z;~;fSb4!76@P#UyBy?bDB;vlMG|5zMTqnumfMGk!fBu>ua!M4X_iy`Y*VXA5AlO9e zwo#40eypHnv0f09y`xJX|3<8dr^Vuy-dyWXR1nU z9U^fa@{8nF5{pJjlf|@hiPjZk0a&1J@`Dc6-=vR1Pk@-}EaDEB_j!yfU#O<$0v0Og zen}o*&N^2@Zw607Ze2$zz93U}q^Sq9al$Hcp--T-NTyy;YzSp)yh!H@uv%YQ8UAyg zimcOpxOy_WgS_H&%{Q@(1ZgnWMFtj&;2(yOm_i?d>J6a^w(nnh-YsG0;!gYNh~^+76uLEMBD}9<`?A`qVsNvm zfd?=elv+OTDDQ3q+`_cRiidv|9K0M5)`1s-p^Ti!Qfl* z0oT0j`x4if+fjc|Uw#6Z+b)Oo`q!AWqu65quD2^16acnyvG@g01h&xPr%2On1p$_9 zWCdDDJS#p|SY+Cw|8Z3$(#N`^Rd3G^*Gu(lZVVbOZ?wrZ$aOscd;Vq?!-t#Fa&mbS zpH8R6TU+~QahD%FYeg(=9{2iw911crEMnK!@$19a_A17gm}vn=lsD^^Pdz{OQ{X=h zY1evWICzl(epW0UC84#qKUoYGFSJK3tvgV0i-ybd8>T~y^ zm1JxSP<@2i=`Pv2F{?^T1j=DHBiQpK78%PX!1g0foj_ zmb10MQ-)kOnI%uiPsh6vt%sjU>YkblS?W0+GKkC;H$`9WgF+M1#TWO+@#Scow9XIV zk28l+a1Mo5t~3BWaGHb*NC$+ZGh!+ZG79a}<<;}31YW2UDp_Zrt6Q0yMu^(HeSXUV zkU63csnOs5P${6~DGxCJstFKX{)D?eOXD_>yHgJ9z_}L4+O~{+Uc3`ZzkVfRX>ZqT z?&sC=2j#p(DRgFyCgEa9;ZOy#@#DZvU5O^&cO6CemK5w;_HN@0Kj^#c^d!XJttAdU zp10NZ>5FHp%rnsBoBYJu|2hx-cETN+*gFpk$ntbEJ9TTYzuqm1bkXv7%k=u$bxzmaXM|#0s8@944-f#QjS@`&jzq$=hW0?^wgQ61u)x8&zHS-b2@#vjSdR)HyGg z<)TeZr#w3iv$5Qp)(TmpkGUA;d*ovQ3C}yf@~6Qr9xzmbgL-Gq`+CP{co`$zmoQoN zkx*4?M#S1iCCd78`C#NTMAUMIAj{fHWn6Xm4T^`j>piE)a2_1T8ESL@d@iB(WK21* z8DDc_Ra8$F!Qs_yZ-7U*2|GG{Es>6OP2u4tm?(%5y%$|Hlz&wI5sA&(mO;-|oB6?= zuph15vN*^@?kJ^)IQ+EiMoyn^MG+qlD#N4QmdZV2Y>@5CJ z=q?rb#PjwYY<*ntJ2p-2{E;B#68z306bb+4RZejovXf!AYliaDghSjDECmQS>52Ga zDBuk`ErG^{XSt}3eXAQw(!b+FkH=vH!SpiOkG!L#&FY$wGG=y5bPOxSnqktv@CCX5kV71vwC{ zxxx(lw(a^TrfVwE$ekXLfW_{41ZVDVE6nq+7}SJW_eddY@iR2miNCqqkzPDWedK-(|S^v5H*UuyORdqp!?^cP4PG4hjD<*SXD{@!j#i=`T zTKRC>_K`%AaiR;v+9p!;xQafJMLmOg3EABJ>8-TmEEZu@o{SuN?S>tGEa)`qfRy`X zU`k4Td6s1hFp2F5N7m-j`whEEQz_Xy;!k#Ju7UHi1Dms>Z`}*_jhsKh65+9jl;4x zpV8*pm5o+L^D`3Q&#mw@L9h*x3^FfFU~m#t_i=W6+6xXdFYScFKSEV#alf!qAj-=y z7xd<_=BFQ{gD$D^zZTP`Mw1+iMC2l*-il58A0g0T=WjBRSuzo6*U=$WwIK@~bmh=Tw@V4Yvc@8a6})LN_FNq#5!3~&u-28?8vf<1XP!dR(3vasl6T(F@E5<`nW8@T~xj9 zKrA!R4~qm0H$7C|+)ZIhW#%rDe+nhJjD@aUWK*Iv0C#9LW7vbu=<0C-wIXa z*{vQvT>LkDL>#vsh^Mu)$z|2mnhEQj!h-_#mb)zHj$OcDg>@%0`&XmUWDW(wA)z4p!gvqZoO*QKUQd6#-=MwU z{>y!utu4o0nu{l>uwaolT$vIPTiZ@t*0 z!VEE1HPb|^8h~;Y`hSQ7n#qyb*6~w^lQxjsL{DN*su;MezR($zn@1o{l5cufc#uX~ z>Ywf@hkkU_x3TL<&#vLOiq+a_{kSE1MsI{M|X6>a@(8*TWulP8W5q(Y)29QtxD|uY(4@_&|ZbYYw z{V!b8tDfw@fN0oq!FJA8q#n}Ek&{hLz^9jB(6NTNk-A0o6@8j$O0x5nr;13O;BuAi z`L39`X|A)uHG&R|x{zhVSfA^9{)l`XU9Je!OTdme$v((VG5im97M_kQ=5hUg4hik5 zZ;a8#J%Q)T71Q^%4OZF<9ThP-Ko{t7DL^Udx-u;69vB-okv7y}$1~t60hLx_4ID)C z8x4tOkwXMO8pm!o=C6UAL^l0)o!bPKO!Ri zfM)?A<#YyZ!D({4xe&F2kk`Dm3`NzB;Q1WD;89H56?(A&R`b9qHT}F#_Oi-!d3yrS z?Vw~EePCaK6=24}D%#1(LWYvyhfZyje2bHU>~^^lKFOI800S%7(daimK3N`jM@C_o z1KUwxi^4j!n=<`5J~rL`oDc`TvcA25{F?sFNcn}_t?&tl6@Wu1s<^6LWNAql+oGSD zQ52THEV)RI|90M0yje(+b{@IG4ZZcnkmR~;(w`G$LGlb|ga*av!L4L<1YwYdqY@tr zI?EiB47k>sGZmr&CmUAliftaNrv7AS_wvP{SjTR{tSECUtz?ZHx3m1H5? zd{MTwMEyA*Fin<8-LoHxNPfm*}v6P`;c*pAp1vQ)BJ&# z>GAqfp|2S{Z7j9VB#|X7DJ3W4vyVkUBD6+6jkd_#&w4>P9d#HjMqn`dU6ag{enwTR zkz*>eRzjS_d*pZd-NPJE?L?UD5{O!K3KCR5Vcr+mXO~uMuQ(<1Y*xp4T5_%c|Ua6o>;1@p)@OtZcp!$|T zM0?OM{L?i6N`#E0n)8eWHQSdk@$G^kc?93pf@i_T<1G2WqRuS z$mFZFSqWRk(c^~gaxF>a2zDuZ#R5o2Cn77PHwNZ)_IqYkvoq2WGe?-aO1JP4C-(Lg z!hji&A8SRQkC_uFD2AP9Z{XRtn>*|mE zMjMBWO?**V*o^c(5VbY17!~_i@gn4;J4Ft0YHXbRK0pCUXO-?$9UI^>ysvav^MFz* zHg`aq9Mt{fe=`7hZ7Z(JK1B9Ji3|u(u$Eam8#gnn=5vLn`KvFVs_gOo>J5iVKdWDf zmAL<}NaE<8n8OyH;j;)c2u&EEqm?e~kj)GPHj^A}qS0dK0;wz!8q~eYM&_(kBMrgq zLhl?n>IuamqP4(^iNBS_gzHkdIJZ%txrsj^kkWApP`(@rUPU=GQ$Q;E9#m%8H<28G z#7A;Wdb}0qGixafDvNBq)W0|T+4*@lA`^F)-BO*MU@QoiQ>M3gW`E!z%+qK`8O4@Y z8P+^+ter^(%8rmP?L(Xe$F@7iR>)W1{932>wT;{TGAw3<4Vot|4|J?BdeXI-hXbXp zHa==wU9yzK!ZgqO6I9pNlcSG{kzukxF^;#rSD8MOvd(XutbjwLYTr+{aaP}r8?-LB z!D9QbZ4TrDHFfT0mCd*SA5_m@Im6bP0n3oI3)WV2D+V<^re9%yvT;57v;G6@!Smtu zG>KitGU4>xy-?;mZfarNyju)dzK(yCp_p2wvYEV~6Cn=SdWeo9X_6RCj!YTb%Y>r+ zvU(A_<6UaM7cL3^*b^Ig2XAgIzjmknn+{|3?Oqv$Q}lq%l1a1eDw{F6sZcakiTBK> ze-kWw4x4p_e*s??U7*yKqaC5Mk&Jv?*t*wTF<1G6y8TucqDwHzZcO*ICsDjv5WTT9 zRxSRHqvTekTjg5uXyaS791QckADzbmt|#OCch>1xb@aNEgiJD-?etI|a09M=OOFfx zy~~WI)kDM>Il(eT!9~7O@=!%xK;Q{=L0ErHJb>rpMNN+Vj$K6L!kNdRc5A^dP^j>$j*RXC=)6`%n-{TD4AGVe{XeThYKEn~f z$&Qm%XT#^*-iaXZWB!5`V!YK&8jQFwH>5L*HAk7ARkbaV1;O;Ff8ldcl)o1K*68#R zZ?XjrlZ~(IQxwWNKT>eUIobb~*tV2paG01S8_kdqA0;-OqQ7MD0_RsVcYF_bbAdk_ ziQ+>1hj()+px?lhnF*QLPLeO0rU-tLiOfq}$9ncSDQZ>8>2>BXm&tlgju3CN;Lbm~ z;TXD?HlJfQrb!G(&6W%U?zc|| zU_Cgd9*wS6zFX*|X54CkGtgtb_I2v%YfalHOZ;Rmsfz{GR@(_@*ULD{4uW5@J1eC$NJQS zQxNtBPTIu!ZDQ{>KJE@V0v^JyPI`By`{8<2RGmPZ(}~BTSk9B zMmczxB0brFzIikzC_H1t280CI8%X`QfGuXDmz$?V3>zUmW-^{)Nq3|c@Oq=Wn2PS$ zZtC&Vt`#wPOcJ6Uqg+|>JFFXGv;?zsf828Qx87xL-)wlcWZ|E%SoJm5yo2yr6=@)Q zCpvBOqQ)a6U@yM5(_y2zg|vNqf5yAvWR$cJJs z+`%R#3Ya`%l`X?AMw#rnm|JY!2wICMfzuQI`qvJ6?H8P{VNe*4+UADnFlpjW!c$iq@TtVLk-U9vCVMA_nKBJjri#H{3|x{hj5}_MC}T zt+4Yvj+k`V@O|g^$ZaG@*@7ub{q=I<%ekuSE6Pb;(Y+j+8SF*4is@KreE%w0p>3My zIEnc{Jk5`V5=&Vrwv+ifwpxtU(c87u78)ntLgYDhoa#siwFOB%5nhGCCna-aBw;4jkF zTGJE9r7vNV;w3b5rExQfKPwAO)(ry@9BqQ*VN`57Lv&o&EGcGdso!1iVxbtjq2W#U zOc=Eo!@B5g(PSfzI5GCNqb;l?)5Fu?dWhd@JeQST>rggZ+-s1H6OCYi?9^|$I4)0p z|3xk#y7i55G!SQUE5C6}D3#kk#*>w_141+=Tnj?R`*X88@J9^Zjwj7!TdLd0)(}BB zs*u*FtyYPR+x&?M)B_`Ns)i7{mTP%b=9wcsb;||@>I<_seXJDKDSUd^coyz@88EUS zGXZk#gnjP|7mVhq0=J1>uu+4Hz*-thXNvoozKEaSx0N-Qq0v|EyQa-ohcZtxuxdqn zQIWR#rd8NH3ECq<`OBWo%5H)Xksfcrv|`8aaB8Y*u5QI*55HEg{aov=XUp4W2a)GO zqr~(1%yliEMLp@JwAPITX8MET>f$tQJgXh}^kEYsT4&kJ;2-$O-fT$O!}v@l!st5v z&bzL&yb=aCePFU^@HS?}y{UeXrg1~(kzcoJz)9ggY)mKw?4le_S74hkI`KT{d*0^! za7()}&1k=pF#+eALI{4roWP(2Cr&0}UcPK;0U-S@s~M)-8&8tt7H>Wn%bY)5zoG5D z<8re%3D&_p+a##2FkCER)X*65#c5u@_)}(2D8BY(+>GK*$$a&G2xX!zpG#C|MxRgS zMkZq#_nTrethji(uV(O)egbPVgytVOZ{OrqXz0B>4yyvM0<7G`zgQw8SX6i|%6|Ia zd3=|4k`9tc{CW_dweZmwGJGp}Qud6r$sO}2b-Y&VtK{LvmI zG>U4Oha-#^R;FE|*G#{L2FjcNdtFrkUvaB6$uKaPY?p2QT z50d0}IVOjVcfCE| zP52FuRWe`;NObI1c$=EVFilgn-JC*3F`Z-n14zqN%QQ%REt z20m;xs{`UyrzTU#v=?7YC~?=IFQTDGzKc&o)QtLMdC+mV+3$5(yeZf88^z3S%JTWN zxwG0BNxE)o`;+=2IdSZ;ri`oI<~!Kahunq8ERiPRSPoDhp*g;NmFcmKw2?OFe2iMb zi@(zNojn}SoQ>R{;P^ZDPp}-r_Et?}bpg+`vdoku6$UukKY>7%KQ9-w?`r<|b%e8} zaT|gs=)X#4L%C(7q~~y&Qze{dD)e!@kYH2$!#v=F?JhFkK{1)N`g7B6k&F)7*W;X~ z{6rJOf^q_b=?P(mUb0XYRmIS>51jRba?DApn>jkA9N>A0q(xW0_X+(T!}{{7JGxv) z5hfttzxA@fkOKktg7@^nQM5ddcML_)uePY?)OKZk3!T|y1RPpIG52@lP7Mr8P5UItAYqy71DBo~km%D}G;{zFj6QM>Y|GTL)^5^%|aPjwvb<%OTD z&kF$#kL}N3TfzBL?2v`{=$oxGoDb^7=^CE%sgiVEdvSaDZpf18NB+ya$CCdAtCCjZ zZxwZKhNu_BG%XgoP5AdKxUowaz-1Y*l+}!FL};9JfxNA6!X1}7O;D;mH|g0J=0uToB z;0`JMH>CK2saV#ajs_Up2M_ZqdqR4#b?cgA>M#Q!`dvq`Q4i&?#5PvEqKRFUX@ZKQ zsz%Fj$Y(k&8Ezt=EWeiLgyfOzo)R07AaWtMkG5`Ea8aDJI5agm@Ss5};)({cq2zTbb8(jeBFBD)1-K}~ApFnpvqijja!DIoxkLrh>A zIdA%X>9EV1jE)hfFgy}76XXdjLb%r{Q4ODG z0p}MW7qWonNQ!N{&eZh=k*-&gHDwn@V@H`|1$nN?-LIoHuTQq$sHB7(TXY?i^(4Fo zkO?nfwAXPLiNj&ZaNZ4CTO_kCOio|v?(aQ9+M3*Kp~6~)`BJ3OTs0QF@nMXl_mA$w z059WI-ET`>HZ0mc9|&nx53xqWFsD;ce*oUM#bxUnvOYm+F%rf3W?(H;qTdIS2rAxt2?S&y?ME@+B%QpcKlCX`ir@m;jEI3L!0Sq+W5LzH{-{- zu-S{Wd}P^M(bIvje*3B4J^8o2_q9!Q!o9k{n`h=fRG_a6=FQf*0V{3pq;D4G=a5R@ zW|Kh|bX1+~4ZYv%)bag2-ku}JibY#rGSNgH8>hRR&$n4N2!jI> zV5Z!mkuE4s&V4rQ{Z01ZwGTbdWtnoCM^LoBRrT{2&)i^d=jk{Y!lq_i-ZkBywC7SM z{_SQbv2VuAhu2)<#)jAJq=r8V%vs)-fd5iqGt&~CPtwc?)_2R*4NsBLA;AQLoQG4M zwm17o71P?mU;-tlRlvE?w1J^|a9Skip&Wi!lW&)1ynD=RAfV_C!%ZzCju&G z%a`vextKArJi@$los+(DoDZ{2^4+$SgTKt-h~7?yZAioZ@z3~fa;9PNv*!=o`9GtD z51loKmFRQB6GPZQZRTe`>KWCsx*RH$i1Gg>n{j-zP$m;3R%(1Ksx-7nLiLE%dP_*E z4vQmo51sVwnVydF#-O~Qx4(|x?6H$pj{N@PRMe9XBd(Z6OF$^eRtK#oJLHcqSeHTt z{a?tGQ@_m(GlA9*rlQ(Aj@NiL<87N{BijbkW=*F=dQ>@KMJsh7%BN-8bCVbL+eE}8 z=nA!)lF0Z*t`K93BB?mYf2)}Fa_60YO|C;+Om~50ECYm>McgwybOHk!w?fw(skbqvY_yu@+a!SV46!1Mu4@9mk!6`Q@JMgP4B5*NdYr~(D0(5Ej z8MFEax7D0D*;bvMqwn@|dzA&Wde+=iKr1ic8FY=~TSqwj06WjPH0?jGa(}nYc+4lM zmsbh#5ALH(LqC@$yM{XHBWJU8)AoC+$Au;w=N*(NqHyxHuJ9>}Aw`g6QZ1M~oU=*Q z|1#${d4n{q(m~x5=&Znvnmv;@|i%O2A;&Tn~&#KX)nQAl(FGt7Ba>}xu zdi$Ltwx16#5)?iwz;Z-ODb;y&jDQE&Rk3L%SQzK>fQbJR=GBb#go+GbUPguL8w7Hf z2Q%*z8!G1g;5vX%IF4VT8F>lDYnpmek`u7H$dMQVzwiMtXVn5A#MX@i5WzXBSosO( zTxd*FH^*F|Lk@ZDQ#vu%deP%}t{yF0yTZ$N|MrhQ9R?6MZKEp5RVGf{2Uw~*Yv;Ir z_0`0pGw(>Sw#`W&mgPuF=1NbrYwI=Isd%x{VYWs8ZAqILF#x)wu0OdQC*mm;zY_Xa zWZr{8z6q%X+_I?vY3zIrIn0|2|D?RiRl4LYcVEBzWqTOkQ2(PR-|{5CHDaASam2bl zU9<+~1P&1`pzV5LDPq;4r}0;)!iM}&Kybo^t#uT_tb^VUS(T+7cT}9IFk|y@+&Sx_hxYv7?ow?D%>+`lIW=W6 zSdd#dN4|0&Hb0NnT1xtJKtB2p0-a#Sk5NQ>-M{QtVAYIgO}#E){Q4KiB{TDYHKo_| zv`%VH6wN@t_D+3yy8;a|MfGC5O4OFTbljmKwykv446uLo@rLU9YDd4wJthZM*c#Zg zKgHdB@#c}@nCleYjebkWTIBXHkw}tjB6D6s@Z2wo5D&!R=dTfVf$2_-L#JCi3LW$i%|Pj|>Kia3(Vc)_R9Hu(NVijM8lZ`Al}@ain@Lv-GG4PlXKq2u)4t^p zBQh6t8PTgE(2GZ)`~Y4X+BMc=#H?xr9wJrZoIjywyFpGJGDVTxJy~cT>2o7N@i23k|?UuXJ+ z2_X~Nhg8aOv3DAJH^l`XKXby7SWZzw^rNi0*;X<5Ii;)B*Xut?8{zDo-P0|dlNon% zgcYnUy$+h!Th{4EnLtt!pLuN08kOaf8KSY0F!iYuc4o>9@+cA>ukv%K#y<<7U8`CC zJkiX-jyZ1Z1@ulN0ad6t< z8FG|QPNs474CdcbKzW((PZdYw#7ep1?u}@7`LA=}`hrp4S3XHrAa^Hj6rNc(;rA0i7 zma?y)+j;*mUr>A|zpErtVo`f%Kk{AymB4i`%ykC!pnx7agl|^{3tn`S1_KV{x=paC zq-J6^4kW6~546gRq!AS8b5Wam(x4#=j1B*W*9aD)>ybS$XKPP#lWJk}4juRqtNmIA z8+`NdXXPuWcFcK30LkfT&MI@Dd&m_nIf-?a7ljJ`ChI@VD+CycgQ6r#W9>B^N+UKy zsLfW6ZZQ*cSSHD?wkQ@uLc%;%b+otNk(NWGlNhS!eDD3>N+{&^HCsV*#R_})F;*Es z(RYnXIvS&14~ZGP?ZX-Qo-jJF_@XfJ8w<-_q03Qsz~@A_5iMvh3OOj}84?x(TWeY) zog)4>>DpO`86oF6)Sai6edhbvCKHGkz5gO{Hnx#pT_%RRBqw~>Don=;obv0KdlE7z zKTqg&lDa32Gp@51Ln>Q)b(!gFz+(TjuFoFeVIITu;(#$d2BP5U!1A0cjNR-^E z+AuFkfdaC6qS*)ZZ9Y2ty1iF?oJX`mI@95<9Pm^WOx@e_3Ioi;Ke5m)x&rjP4|tq+ zRpYl0C+eV(Ro({mceyJGD018AQYYnSE6|C}W}`c`LIs<`7nli;2pFWTEkn1NtCKx0 zW&vJRVo<-!3CW%cf%DO)S~x=OByb68G|(cpw3`Gx!q`{Ad7Zn0sNtMHd-PDJHTGc1 zuDwJv1GWrTxhBBa%1})B^z!)MuqU6G$2GVH#6{Z#n%gB~!fe4P$9Q&xjb<=`=3WwnhYvM-D!aX;uZyjmUy@f(3LWtX=d9JmSmr<;9 zr=I~_Ytg|#*iilNh0nzt4V^h&T~9YcF<}*w49UL6=riP#(ni2vyR%_GnZ;rC(Uz#cV@{gxJ} zPTY3Z##w=nL3)4w=*f?dPd6AeO;UC#sXGOwyXlR8aFt4AplN z)q%8*>!QeBuG7h>+C$=Zo4=X!`{xMaHhM)Sh*Px18}p}Mz2tPKw2o0pQ2i zPVj?~EkvFVUU%-jUSXU{J-4ZrMI4EFY3PuOjPmv6p3y7szpG5wn2M}j(uYP;Td2JV z(NLF#B+<@G&PlA@P}IV)5JCn`x)t**=r;kHY=SDo-)1%0Q)(Q%qzX#ZfYsrO%iFiH zNB)Sh`nhV5EH?PC#_@%>QI(tEJmjQub;Pd(s&7KhU&4}*L|A_Z=O1I3yA?Q)U6;|y zjYTAx8q<0M#4Ca*^9ZPZBCv(-AO#;?{w?J5x}gO+F}=7*qI+pg#m*7XfJCOzZRABi zN6Ok($4i7?uo=hWGXs1+*HMQq=qQAzGJJm<{Y#H><`-jRd&OWCkyc!pKtENjv0Bj& z(j_ZADyejJ`LY1qnparY=2DMJn@P8UwJM$0bgI~%HP*sVlO^XnS8N!h>||JX3ckhJ zo`A534M1X)K4jMSQR14#C{`c2&&_`!0T+GQX0ykQ!3goL)$Adamu{%{0m_c_ayCW$ z{6}66=X(n4hCAuQ#r3g(WHy;1FXs&!ilem^H{;Iecm7USwbCs-oPrI^7U2OV*9$kT zaqBf9oUe~(57$)5htWMgHnggT=~NPmcfAblYuTJbV>cOj@RBbo02LE6z~X!H(6Ww6s^QUx=F?@IFMm>%PZ9a5xj))2Jrn9V8Kb8Tu}#Y^8~ zOq;N%&D?1&nbOk;)0gT~>a{_tTmEADbzhwm!fo=8_jbQqbM}4vm%>_vcXlC9t}tWH zwKy73dqo2d4I3O}Uf3@HX9{!+rYQyN8bcscVP2;p@bq^a_a$2g$r@psh_(|gJpLa0 za(S$yker!e0DBYkVnWq`r$BiHdPXR-av5vwo)naxg>^9;mDA-^M=+M3*I zUP2AEin@lN&8Mv@v!X%cJ~h;NhFDhzs;D}+7vO+IElEnx>%`1b51nIGHb@cuiW5ld ztSUPtiNifwCri%Xr=l?S5=sAYK}YV>yNw9xNkymb$Rl=()>cQX95=iV6&B7>@*>eC z&nPh&cq|o+^Q#Jd0=FIm8Z9Kf@fX8@Y=y})7ACCeSD5YhGVi)BCej}ZD<1N`S2y6c z-UjqD*uttU#|ZDvn?}DQ3S?{7mn_j5c~(B`{-FV}1v?*II}-1Yu*Yan&F5==r8N`u zlZr!|_vlAl+p2~1$J-`htK2bNt)Aaj1{alBqDp4!_PxT~uU%NO6Y*M)B0UXmJW!6Z zPEgnB9<+p49F2-emQmKL9jZ^->bZ*N`QK78_UNTH+tVqq(=ymA`HZ=Yyv1gDs}go! z_ZjP|5!a8)5BIatt;hg1(Y%<7dokxfiV5WALnd=Nfx_mp#)aa;acc^+olc??kh zE!n`u#h;`I#A~(x)b5rUDTGS{&iyD1IHBhVPlQs<@g2-)kzmh*zLNF4*+5j zs-7#5TPlZRk%IBr>TyJ4jL_3t9?&JDqKondSRJg8R*151vx%TF$M3)8wY4{!HWZ`^ z>q|mq7TZvC=D~TH?NB8J1?Z|~65YTc@0)r#&uez-V3HTgW+v`U6tat(sOg-G27NgU z*)jl0v`ad|%-bl*_|T03WKxx>SQv<()ZUKm4^+?rOA6XOAvpieJ8#!s7c1T^9Frio zlNS}Maa^0IeJ`z`@AA^sQtKhkg~uxdXstg3GG$F0v5gBHwzT`HvNQBhvkiiAW~d66 zsX-tTTOfrEiH3;2D~b+Z35MY;d=G0Ld=JCCY4O)Yqfgh8K-)D$=Gq9L%5a*^vdRXbXHl( zL{$aCp-JW1fNMz#(-`Jd8b@!K@|_))e(+TQG#-?Vf>sZRe|p2*Y;|rm_u=L5Oi?_m zW4?@ynEFAiHpp8?qi$X7N4w^26|Fbh{{m+|n87pU7l@+=BxbV*Cm2cSGT25nTfuLJ z@R?-7ep=nz(bgBB7eJO8n2&}J;r;S=x*$Nd7hG<>bA+=b1?&l=w-wFn*cD1aNbssg;|Y>k*LC_KnE@=2+wvmLCmL6%Mx|Ip|0GDp|*4&U72^5&mu zGEw&1bg+diH4ym(+WWPA7v8dncYRHkq=28@KHis&vzjl~QY(Na!?g#zaCx>U0-n#XXB>P4S}}G%Ic^L%^Q#dP z`XNOl5!xothDbQfuRSJ8N2g||H*r$ZU`mm|nDG5uB7}q34>>R3v2mjD$x0mM38E2k zi=ass&$q0tWL-7R?Ja(F`L7{oeA%+;=}A9um~Ewx$+-jn4{w zAcQ+Y3#e|7ymo_{)1Wb*iHh42Qq-zl3k8C7A5XDZGswsGH<}QNwTfB+^-iArC0S}< zsd+B^cZq~{@mXR5u5KCLeq;f9zZy1y7vmQzLzTqxMceNL$l^S2Z?u;KDLFRe*K=YKMwQ=4F~h?7@IMe5GOM2h;&G_$vW{w|Cp%_bH$x<%-adj2@K*Bb14C6$_t<2OMRy_hfoG;R-1`aK;uy>#^ zmW+TC$<(rWkK8Z;|GBz#80~&SU>mAV1J8*t+Vr9vLA-9!#Ib5HC>M~+0OyXOKm&9p zGv-L_+852vqSAmo_&?uNI31vB#YDyLhk}e|PQ)~lmHu~%6;W`uWoA5Acv>l3IjuAkQ17t2m@K9Gt4!$DM6l)3jHQ(D^937alcgcx=XZ|x&R51s z9Pr!Y$<(UWxGd26asb0S(A%#Vt5S(>TU<{TA^MD=a*OI#Rpp&~l#)`id_GZ<%EAAF z3la_r={R{0pctT0S6-s;5?(Tk)hw3p3!+DQh=t?o+lWC;60jI^3Uq*zP3uK=JiyW8Nwc|29EE6D zpdt~5L7PgP@tQvoC7?|HszA+n%Jk|ex>syMbiU9qTedSAOF+P@Hctp>B>$AujS#z^ z(D0joSvS0WX4O%QwI=up^x{Dpu-Jyf%&TxX^49H2eFIrK@0hk|*i$M=l8FC_P_xMh zrP*0*Q{F_^nlF21qr?9qO?XJcgz&}CfENG4XcoJGYukqBf89cL%kb91sV}XKCWErg zlVhR}DrRof04+4(xdnVaPPITTcie8bhbd%PDYZ-oGtanw*P&%qCTN5SFA>Db@mBRj91OKHlXY=e>;je&DeKa;@;-);L(w;&DiVq=uzCl z9tYoKnU+7R4(CMGokM{-yhLQz3#Kz=C185l19HD@9d&|5E#Sh6Q80#N>6`&}ZpYEF zSUh7{FUR~EX$r~P4Stcr3hR|KBR4c-fRq`B;B$MJZ8HD6UbnE#MP@AbG&-Pvp9ejjX9z|*7U?k z_x4#vn^{4(l{n_(fPOW8CJ2}_;hYY4jCQQWOGM^onclCUbQ=RtT-Evct@_mCVc#2v@@N_Dzg!R%Q@cWkEMjssT~R1U2Z;2N7v0 za2Bb6iIJo^qO4)~@r@ZPdvWSw$?D8S`~=XCqMw-v;LAa8nK^=Gh0@TdX8CC60jQn* zJ$=l+AI<5*S87U9yn?D!ekmp(OOdA#359Vd-!|i?K9iK3F^05t6(L4#bcTR$7wjO| zvKR&Y*apU;pSj>r`6%ZhT4j*cjP_f6NG5LNsY8D&27d1JFO9w$p;}*FyV!_E>=Wgg zAU(jX;4245WcFA!vTc&3)0jOMBURu`b8KrH#~L2Rv)kFmz)3NQo>PP-gSpZ>;PVmw z#ne*%Ed6I~5em4WV`$6axsBX_2e)S5SX~>V(<=fzCummrF<3Z*)7vkA5rBRjR3o3o zzy^t`%KHw?>B{?@fnStWycA;c#D6Q)CJ7t_7dCLZ-&RQibb~DR;ezNR@B;n>`lQA5Knr|=?aF(EQrEE9 z2CGc;AQS7MBP;Z!ww^N1cr^`Eegqr=o566mD%w$qdr41uQD_ z`f0ZXT_i1RTNamqiz-J!U1Vwg2!vB+j3l4^L5Y|Fjzwc;e@0)1%5sfp;E@=!qcbPl zw$u8``wg2^VGBRc=qqkml~ROM!jG2P(lyu$k+Eow;ety=&86OR$wq{!MBr5MkIjE_ zz5>DYey!|35dr|`pf0iaZ82Fy0){r|!PRpZxsjAL@!e1GahXscNVr@2pg-%u;KYoC z%mclBcp-G9_zl0lgvjki8v-supsMwC_b@A^AY+Y>r{Z4m5d@JCNV@ZB5{*QdGknmn z+B^tNO9z|HziodqQ{h&EBzn~PSeG%K!Tbll#A)pr%4#bXbNo4(NYH`r zRu2Y&k^`ehPAH#QnGpI0yz4fq*>^1G6BH;)mS)39-=6V?hrwR)$B^;`c-LmECH@@s zF(yCutMe8S!^hJP?6~16Ax7x?muY!U$h~hbF~r(4k+UG zP45WUxjCnf{}=fD=xhY0Ok}$^rwD;? zy1F&%G3`(^w$UdV?gve*tA9W+6bVNSg_N=ivUKqQmA=2Hm#%ZOMBl|T8~E}_=o#%T z&8ewd-1I5BheZx;5DfXMCaUk&49VGg0Zf<^{#M4EHUJ_lyntJ}^B=hZJ?iBzPiEC9 zfZ;_m7Ci~MKf$||s2=!zK7J>Pc;sd>O8MYnrJ@Rd>8wN@>Dwns5_9&2#?AG&!9n0C z-1MBYjXVJhjMgM6c2iK`lrcM8w70AmQp-q@YsO#LY{kM0IFU?QKbjobQaFb1e!@pF z#+EouH~}=PV0dkV@^Jyf=j$~0mjW_myyT_N*2ZCPLe7gdbd21R8>UE5G`brv5O4uuE$ z`tcjh@t>o{s$GsLutZUk8#gOe3y@tsXRJKEd@<6sc_>g%mRiHV9;Q?frmKuE{1Wtv zC(3TtjJAwFA!Jo0Xst5OM8j!TsUY|)uz;7pGRgWyInvfU#N7Ra3EWC^w$>ydD|7^< zX81_@`LZlHfr)!`YIBR=JjWuza0qSshj{@-N{CrPn+=3T%olNv$a9=Letk+B1c!^3 zB94{!OJ5Zo0;I17xBgwWETn+*8}@v(DhtC4&tpK?mV#(a1=1ZD8axTOymfo1y_5g= z7aMf7nQ!>~|3(%(jzwKQPvnkI0Q!JQWD12E~S~62|`5RexB z4y}F;v-1lA_<{7kO><33j%v!(7U#C;Tc25s{M*JwYLsHF{9c@)K;1;u?IKcVLccNF zk#JiUM!@+B+d#XY^s&-e5h&J?RVJX?u%bd$aP<$+($$Pd&Wx=wQQAA=yY}KChy3}E zMa6<#=Sa_vv8E^B(TL0^Df-@D?1xB8#l#GOCeo6Ln8%bNjn^&X%uyk%zMXKG^^r5` zOk{Y$OJ|N_+p;hMer&@;B$fvaH+K)&?tY>fa|TwL#HktNbl_Ocr_YgoMwdL@b%WLB{ ztJH!adF|TRzx)fRl+-PKyz!0F$3L!icjIr@j1COZW-BG7^0DK1NhBP`eeC?M0mwU0 z?U=#3^N*eaQX1q3OYqV2JX#2tZgvrZODR$bzsj{0#tu8|QE0-kr$=F8`i`XfWmsLL zE%PnlN7hZwX6|?AF>?14CjQKwZxX-wMeOyjCxyyAV()l|T3(KQq(M9`Z{G?32i@8x zd7VvloCg-%@Zx}a(OyJWrVIyUkk!342Y!hGFhR`>`KslPJ!C0{?)|cECbamr^H2JS ziP1Xb+>4o40cW+kfFK-Aoouj?E*h*N?q>Y*%VV#7EiF;|Tc6qXX^D3UPI?aon}Q|0 z$!aU_mtJB)4?$baXo@p`0uF>zPgrMB=M#*i9(ZZecCQ9H31H%;n_{nf9jQ#=BlecJ zn0s~(9xYBj{hV^LOtTn@z&HC<^uCR~Ff+yNT* zBFwv$@JN(oyj6F*tg!lC!>gb9MljU$WVQL;oZHj+6Y!S8v5r0)1u_}%4uR}EaygB-h|47R+t3&$eN71K=K5v6X<)Gr^mKk>*NXgNmfS%rfImk=^KY<=! zV5(Zf_GBO)ik0wahCQWZ5k}75uZHPX{9*{^Nx<<$%HsCgP~JGaV*La^;SAV1#?stm zGIs8{v>>xSUh^8Ipg<4An5iUbG1FB;dz4PFQUq#z9uJs+M7^ zpJq%v3|Kw3#Gn5h&8_Q89n$;Wr*BTltyTC80qw~z2CU+B7Y{@Jn#r=8Re_i}jn#v- zGGb6qkdUI0>_)##!Y3b3NtP|LmG=wf`05LK4oRDCL}Xc}e~uvYAzc|)?{HB>E5nUzAh70 z-})@0(p$Aq@M+B1GArR_3#Z}0|Hj)7KV+E1))2a`w zO@~8+;Bk>#36Cb$ad@otS+aB*EAN-kB-8k#wHZ<@CemgxnR5Xjts2QHFC=){&+V{` zk<|M$s>=Me0iWOOc_weaT_|Ql_z0hOUgo!DfY&7Pu-N$lod29#_XR+S>#26cR_ze; zy80%}tcqa*62j;Cn6-#TH{e~h`YaaC)vnJ5iqeevB7oeG2 z0cW-3sJVLxJZG}h05x*Vh6*H2uMw3#`&m+fvpnAL2I4DB@CbDg$8X+PR2P#K!|oDI ztXhkNPit5dG~U#Te7xIG**M33&^5%=>-{f6^#rOkfj1x8CA2l zoWoFj%n0Pt9s4AsGh+3PT4q*vI*1Z4%;Bm`=1RaINXoHg0HS?y*Z6@_#wZuq5WkOf z0-?pF_X?zmfBV~{0%v!`-u-U!I}Gr4WHyf>kGKb1OKH@~f^?({YKMq#iRVAD%6i9? zSysU|sYD~-7)IZ`$Kp&XnFw-O- zd@%NochEY_`G{Y7Dft}+rvI!^3m6xQrEY!^V-1gt^z9+mhcLl!yVZcOIbMb9P4Ibv zA%TiF+<$Pa@p1AsE~Y=P*agPV=8?^bfL*@ymO`7z4SzVj?Bz+fpAV(6!G2@X0$-jW13fbCTpr~?$*!=`lN{sC5Q@h#R z@rlYm{Pn<>CrfWkDU$TL&(S)}?TEeUO`6>;Uhom4Y*)!H0aRI2;$Vbr=X=cM1kCUr z4bu|dz?p- z`4{l>JH|QJ;|Zjn**1>%aLueDCeZB>S&yO_YtTm9UOZj+jmhKJ4-XzqB{NhMzwEL+ ztY>)ZTQ!!Or0P4?Pqi|fWM%V!tFNC^jg~a04_%?R=XMjVdjG{RakfKBxM=AGiA>D5 zoGSXZrexe_!}+zW>*gDo%NRIs%!)hd74y`(G!kH7!>_<#MEW?U-$u+7J#?`=c9IuC%&>F?=X zkguLkP93{W6Y!$Z4nuTT6T$2Q3%bxI>0t9vun8}LdYkk8H&vbOWf0_3z@X3eK5|Y7 zh)Suhfi$ru$sBkvR=Q2Oz8A0kfvH|}yy?+T{CL-GsYGzB_1V*hzdm{57sH+tGoK=W zT3;Xgw|~oeZNr=16#wZ@Ls*~>z9KJ~n2Ajn4Cu)_iFllDR?a*o%6>cKtJb&hvk)gj z*0(-OfGfnDk}+K*TrG5X9}{z=W7t(Vp3P29$Z?BH5`PYf|GR9-n}9>n6fN=RfmRLcnlb^5iE@6@6>8YojLT+SQE3q${svr-No4v3I>o ze)?&!Z$#P$(~&b9d)w~WTmWCq_v+6iQVBnbps*c_M(SlofG4KYrsv?VngUKqZel8! z|7obP&{ILM+FA2D`SP|UZvtMqX@c$mgY9+u(|Ea=Nt`)s`_UJ^K@0fD+kZu#mlH~3 zqdvF9$&&S&*Tmlb_W1SJqfslk@66a*c%nYf)ZMpr?dAe=70X!y*u7Lj56k0hE2$YF zS@6i1dH`cfTV`h0ln*gV%J+WJGqQS8Gecb553wab0``T{Td3Vqs#}I1+c3450h-VL zo<3*=q2VDSVB$*rk0pQj+2QM7Y<%&d;wS#;p%3EfJ!j>`^`2Jz{8^&LE1rp zxI(it!iur=8FM}f-iTHj;uFP!%E8Ca&^Asc9PbxiLd}iU9IxrSafZP}$XdWEG-cOa zhgWp?6?8xqu)BC__Y?GEnEr;UsmBM3zq|k1M~?n{;^_B=3cvk{XD&JK>B~U6uUmHE zxldm5eDx;sJ^5p@(euvP}mgfC0{Ri2s z8VMdxrYx&{eF3<4bvEjj^=09z{U*xHgrTFs3 zK#-s9)Ryc7oVfmaG~Oe9``hyN?V7P}!F)9wP3 z;k8qd8;Ru9?kCViY;SHoT5!0%Woq!L)?2%y_R*tmqvz2VgLcob1`~aVHk*>V5^64U!#j0x{9SEnSxH{0= z2X_i(HkV{+f9v|)$Nsy2|D_WZzaI)VlApNHa0JZ6TXb~bSh4AJ9JY|9X0rSR+2pFs=F?V&k@EiC)t%!sp(8};< z85O&Q{vwD9IDXAF8R|8T&?T3Jib^~C)BQdAf|!JoINY#m@4>6v_g^;F`fMt}(7>X? zO2E*EX9n~j0y}m^y=>RW1dVCsEJA%?j0#h80EWC3nxQ?b0r^NM41O}bG#VLgc&tnZ z+Y0a{i6&c5GhmF}@V#GTTA99pHa#5;ZOyTRg-vx05 zn*%H0!SkE;vm8+GSkp?fl!7+1<}{KiDtbQv8Z(I6WTb2JNY@t4I)NTSHg;@ax(T{* zn0E55Otd)m0#;gDVsC#tE#0Z(oo`NDr%%u=Ifg>bDB%MQ=eC-i7P+C(w{v&qi)_$X z6n_HKWcHosGafzTijsuhDKng2GxE8r(>oFp=p(Gt4}u?zPiU}sgQ2~;Q11U@}htb6mT`b602*jfMzJ;{X-pB0h?%Y=&)5q*7 ztyD=>zV0{s^ya_Ij|ND;jz4vau{ewrg^z5PEY8xjqsXv)fg;PZR-evvWgzIs-Ov ztmXH*wG)fZQx!zWuL17~3){)v=J>a&JQ!=yt-l=sPBPnyfH(IpJMXvGQ`2>(zBKc? zcYd6bi;0`^2v|LMFz@=T!i*X6qmR;8Ry_qR6pELRrJ_@5AC0!XL!Y%6T|oX4*DDLXwU9d|YypKZ7eFqhcmdi!YE_RCt&X4iYGVRO`l?57gSA1sk8rUHmh6mxNgah$xEDICt!8^ zcCfCjT-hT&{Q~({zoM_NZa}@DVfrjjz-Y#TrmEc7*ecwz0lEWYH5{{frIJajdYwtE z$jFfs+aA)*%px0=U}H;eTZOt{cymE_n~i~iv7@g;ENwr83x60@%=e2m&#;Q64)CQn zcN^nm&ao44L3{l9zI&BY$gQb3;6H;GO`qj~+5xz}RuQij3dfc=&}SV0pIL+_Hi>S| z?8``DZXAn?Pszc2)`f+70Vt!{NNYVh4xqqSZQn& zF1m;ns@0L4Hcfu^*~X~YD|7B?6>{v$e;*2F%i=K5AlL;Evup10+6pGMb5FFuAR-Y@ zBw}%PU7<;wU@VSdR`{{GBJPvIgL6191!wZk2Ia2TKiai&v|}lKHkU9{>T~AH-(}^> z9+$m!Gj*XomI8*bmQ|_!k+|XtH6H&gD%M0mXOw3%yEexnQ7XxVS_Ak?_GNJfs;c$$ z&?haBb1U8L{jo{7jPLqK&@c#?>T|<^ARcICgIH{ejUjrT)Ja&o4Ge|%tNZe-Zr66y z$W)U|ed$V8uIzEin{%lP?cobp`RF6z;)_{{<~gQK>wV&%k@Eni_z#h)Zj|FYA0HIx z1TwqDJMy2o$r6^x!X;vmZZRzE5F$9zHpQEha4|MO^R3pI`$_IHgB1u*5cS3QB`529 zSWN{B8SjMmqb-#UETD_T)=bVPCD1kT(pzP5|bb@N)ipp8Y|S~i)M{Q zFif4}ciJz@j<7V*JD;J?1gyOG zo^a`$1hhSw)^ZNSqJxPJYJfn~G_o8O-A|mX#x@xqMBY_(xGpp>zJb$tNZOm}83AwY zTXx3FISV$j$Bf_2IU4GKH#Z#2+|!``(zPgA* zxaunT;fLX7wKN?K4Gg4+$~B0MBZ@_TRtZ=EYfJ_U4Jok$OZG@Dt-;3i^jUM7p_NNU z0d0$QvnOF03hg<*=SiKZizI~?FtT$uj0hd&JYNiaSFdTka!#ts%mufx zqQwXJ*bjbksOgTv65#qid0dv^%8tR~QKfnI}Kvo#6Dh%Z}_PP#Uv2aA$bqCk(>NutD# zI5;HMxqC2~Cstxv*SY<=ML+rzUOIZlYjgf)*#nYd*=vI@zqfPn=}pQ{KUN<8RC#ls z8ZtNW^-#dNdGGu^J~1VL9mWZRPoiRD6)2e%FxS#r^}%@&{;)dLnk^A`GINbf67E|e z-ur3DV5)c6->B!7sZ)crU_zkzp+O`3K;hTC6Thtb+>x#ZZW$jU91K})xbxxBwR4x< zf6uC4f;B$#33U@6fz$j%sjF-ec#85w*p4=`TQL% zt)OI_5(uS@AA00UHqE>O244$e0d7?6kkH00I;v}DYvP>&f53phFK@E+bS9&UC)eGs zn`5?Ypo=gU0MO8@UZl4aOTMix_ZCgUWFu_1yKevQSH&dAX$>57y-?;0; z$IjRKeMm9<{P@l^hiQvRG&e(-EGh22Jpw+^$sOegHa9{=?8t0A$+LuokM_C1ofLqzw z+TPpaV;89ak9tSa{r@D(V7%@4?kC7IWDOQPHfRT>sE(TQqP4Up_wFap6pieG8&(Gl z_pKZ5-++HLi;MW0Dx@6|rJ}QC!mphn;x`2$pcZfixiFktBHCT-*mqG;utec^{ z-`A`2sv7#t{8qom`K_VwzGDZTC(n?*qbP{*Xt~e83Gn>b@!rS>tMW!%&QUG)5ILP0 zOtga};W=74#*}`na#VRi0rp7m8t$$@Hcm2kTaOZ{jDU4>#oeCHZeM42Z+CWPEXfx! zakZDF)WiLo#)#e4sb`rs_lagZ7bnfTJ{~id=Aa1l^}}=F2G3qlF#+onqr~y3kzZvsj93#D z)7Ce!XhwXi$-8e13`__QoM*6~#hKrMzJ9w4MKSWm+w{rOVCxf3TQcIn@%`BnWe9h} zOc*Sg%Y8eyx>g=9nyEi1_7C@Q>aoBxGNwcE+A|xOmrf-GjDQ>3=ktS-x&OVWqBh3p zuC#PUJC=@it)$PIpe-|Ox?UT&kBvn3^~M~pq2&V1z+ApkymA6jg48-Ix(^?C?v&fo=F#EMR!L=7Ph8#g^0pC$>G9 zk+V-1mnee&tfZB^GgJ^ZnRAC|v3PLZsoDeA8SwX?o->)CcOHs18P(%VEr)K_Ao#kn zlXa~o8zH#zCNmu)y=%}O5g62#xanA@DUt%IMgi*+A#pMuhgN7mOrmJo!a%aKz=eB^ zLe`00i*Yx>ZfR!)s2Bb`Hce6txvK}e2>g-u4YXd#Na2he3mCDOvFZjsk8&&UuYHTc za95BfRSoXCSv_(JG*^e4ZRU0drBkH>*3I?@Ui5%PSt$hw7?hlH+{xiWR?S$JJu6`6 zr8&lWXs)Oi0;R5f{|?|10rKmp?M$RUljP*7jkf+ zE*WiIO#W&^5#Qy6>J=~|90*3k5jfyU*jqdh@A6P;Tf$ME01G&kOrql0L@aLZ0G#J? z&9TUx6K!p!Pq_;8HQanm9W&b1Fm&Yi;I)!zs#G$C*4BY1jt^+Ne{Uc7w+^FIu)`Z{W8<;b1^>JH+QF1jjE%M(^mTO~-gf}^&^AQF z{M`UbB)xmDQta|B4iQo**SntTMNLb-ov755>byX}U<}bq_K%V)Zz?f1cI3bD&rxF- z&uBl~3(4_k7pVaO>*mzW-fko23y3w@!G`U%`XkbyJ5Z9W4qXGQ3Ec;6-yy zB?im}eTpfQ9BY1K#J?8(j9qTFoTl_K3oB|yzzA@Dpz#?~#=>EnF*l56=C`C+TwJnZSRPG@)>>B15h+b zpRGG$O&_BlsE3Pm3vG!zUmwFJlZ`#va}zPc{zh=<(9d{0lI<64YClS(#ssXJX{Ua( z;C?z#)!se7zXC&agI z^R7sX!dUUgL59C}3Hp7g;vG#6h5i=}^RWA&v6xlO^v&V#hh|Qn(1|JKY{Hq9v|H4k zfOWG!+r4E6__RVY6%9wYhEe_ebMd1+pru_@6Y3>Qq1E-ysYwCr=E{K0hmZKX zd%+ab$yHI5?!H^N>@rrU_J=TIhIHqh@`DfRm2TFd*WOf_`RLx!XDq(&D6LRifZj$s zm!q0lP#1Lc$d$znhTQ-K16`ZL(I7M@39K$2vT`_F;tI7YU)MCUw?X ztUetchEsj(t?)VYca#xD6cZs&Mjfp1E=a2&$Z-Itv#|{KLbOdh zIcUr}%xpOA7Ih+EFvz~Hoe|o!qf2`sHEztjC~a4}G>aK|$$I0zo?z5z+RjpRm--Q~G;dyN$`n?LMIYkLHyiPAMKSvFvUeiTb|EUZNy*d-M)KJ- zhDN!CS+|4MTETYMSfbow_?_$Ya;pG_LVHHK8u0tgb$@fhAJ8*|c;p!usS^P!D^>_! z{VFTM5)bM2+bf=zj=%dqvNuIMHfToWfmgK$WdkoxINGsn)Lg^RXAV8$j2#Mzxhuf1 z0kF;sZV{REDPcpOOI>RWK1~YP4hR>&{cTo$r60nyY2q!nRCs(?RYTi%(kIITgoypU ze)?=JqKGH9{8XP%AnusZuR&%Ncq^<%-3B*4Z1V}SBs=uRi=Z9^oPOn%)YPf0{9HMt z+ip{qEu+7(>?j903jmb?)GpncJ6V3Hxd-sy2?v7MkfI3&im~+>lXhZ^txY*(V#8DT zXK=Hrl)n8ex)P}e0Sn*x4l6vjj^x+BF5Z1=%2=h4T3W*mtLU@k0)k1j7;?>lwVDz7 z$G81l5=C%veVz2)+^jO$IWvh^oa<}@ax}ZdhmQ6x%*{euIo_^N`vQ(eOBwZba>V}n z27f50Bd-VvZ|0*p1T}GPeSbAW&OJD>@t%OMlX%e(8~VYC7Y(7T)q959R}3bzYv{4w zGUWxhOU(;de(^q;Fh!LoLYOKbGxkUCaAL-8eN9;!4Hs7w@*2v09pCvl*hn~u#*=LR7p&iFwbv||+=RbrIJg7-%3jFM zZE%sA7jO|Z&jlY-rbs{e3HrJ~TJ1L1-^%?f%7>9k35F`07}w0X*$zvED+^^v<9ip3 z_}4-pfE-O5tV3|ooSHtJ)|&^1_=6viU)nCF z7X*@MC)Dzzg(H#0@6u;0LCuwIh5CGhf*&QB;<22{N=?M_;6fWPq#R&TB!;!QWvUu*(Sb;OOWUJ503w1rz~P-dV__xb$QoY`Wn-)P&CV3$## z3SP8Lpv&4@s~zOfJpS=*KhOS}d!a|`xnpWyz~`L9>do~-oI98PViWMC8^S_GOtBV= zr4N<6Qre0#XKtJmG4~3_zlws88Q7lQ^&5R+g5jyRnyX1-&za5Dv64nm29{d;%IYe& zsCfYk-})A-H`fno{(Sn2bNMor_F@}Ud&2L&F9qr0%8CF^X-(8@q0PteDptMSKJryf zRc-WUwVgWZypA3E%}|unpL*>m)x3bk*|S-_xqAp_oPn~?_H;-}pzNl&+Dsp}+`odT zMCG$?Mz&y(6aFK5?>gPw0F4qDHm43#$6&+JRKd~q_eQ%Kbc>zMyrbp?EZu)UD>;{s z3olewtf0Tx0x-o31Id`;Vc0{Fc-tt`uM$8lY!PAwF&5&_{d+W3ON0U=>$AfOWFlHO zD^-lrWoG&QM4VrS1%gMPkdeZJDWe{Xvf(x+-4$wHz}mijwBFo4ge$HHwY3*C(;eh{ zNJxuiQL)(56WYC(K3i$59M1AX3QsXtbqBLK+O|a3lw=~APN&Hr7G6S0DQYh=xQd%h zCZcHg%y)ERX*&d4lIborFJRsKM6`I*P4Mv0kO@3phh8hF_q|}UY&mMJ`&2n@H4u-* z*gQ~0Af*UTFdB(~XyIu>Bn;+JW#V2@6jeoGSJmJ`UW-PO$~l`~uMYuB^XIdwbL}|q zJZ0%p^6OAc1zobkwaa!Vr5#B}t)UbWt3OSZeff^OfKDpDTpsJhih>Bw?&QWFNioCN zQmaFQ$f5T^wU!vGWhKd+^H|ew_1v!mgYU4rFPeG~uoj7=&ODPAo=b-?YnD~n6FeKu zSZX+7pbtMt>Otggt3<+o53p09(O>*_o7= z1d^hcN|x4d(5(M}3Igr8pd^BKASt5QHQJF~DS_ODROe-qsazL^+=2Pn!548sB?8xM zdPkiISOZt>+;eI9m3T~aCH@Tg}M?jkY2g6bUQ3uda2fZ zYSk6682;{_p3bg5UrE)1k|-L1vLr$Gj~_Dx#_6K^1$)99w{X3_>cMbRJ@}8aP_viO z&Sq#D1BiBLV9T)s&+Dc+#R09uL2SGoA?Dlr4VqV_hj46AJ=^n|0u35bCy^aS#`)xi zJGrl7BMkl*ZEQ{0$xK83MzV6F4FAD86tICH$PYb~I^zshqBe&xeY t}GGUV6elT zZ5?ivC_t}|8Ugs{v6KKo@evn2>a-Gi^>zAWm4Wj~-T^n69O*?943QwI1z+J;^kh*2 z5*t|1p+k3O(7!=UWM$7*ae6_W3fM#o1f)CeNS%E)tJR!i>Qv#v3*{GHuo~|rL9VZA zl*p$XK2(Q*{{|o18BHwf8p!{5I75!bDmw=21n@z~!5FVW{RPU080a_x zD$SOYshR*jfn8+h*rETxYwPH_i7}6;X8~i>EnB4d^Mxy~6fU^H*w-5*ea<<;#TSd$ zTq8g6gg#JkHwllqr>ncGt=)@&M@R{xAT)-O&HeOXMlqz|vyAQYsvL7i5=Rq&ihwop z$VrAk28nZg=i_JtH1bt_VnCStl)-gkM+)W6MzO<~=cJ?El}dkn`8X{E>;*<@#Dsl{ zZm}+y-8;`ndX-@9qiY*e-urT;gL*FdtQ(L5M%f3-=4YgEM#;J=(2ro#3SM+UY4c<} zAtkbLuk)))VN$@w0~+q>?Cxl3^L2SRkzh?!Top{Bgi1Ub<7QLxVwC24qYc*q4a8$~ z&dEhcU4enc^(6Vy7@)eJs#~?HrBcT{Y;Mf sTJ49#jv?vhnE&|3`RL~|1i--m1LRS!ZV8xS4gdfE07*qoM6N<$f~6I`AOHXW literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html new file mode 100644 index 0000000..5eb8ce0 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html @@ -0,0 +1 @@ +CodeMR Software Graph
\ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png new file mode 100644 index 0000000000000000000000000000000000000000..67f0756412f30c8755f06db0b43d5a57559815b8 GIT binary patch literal 15339 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 Software Graph
\ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png new file mode 100644 index 0000000000000000000000000000000000000000..b7c6eef5274366b574dd2b0afc271bf91a85a8ac GIT binary patch literal 25932 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 Software Graph
\ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..93b066fcb694309f832fd4ed79974bd1a89085a5 GIT binary patch literal 10401 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 + + + + + + + + + + +
+ +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/circlepack.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/circlepack.html new file mode 100644 index 0000000..1c6adf1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/circlepack.html @@ -0,0 +1,113 @@ + + + + + + + + + + + +
+
+

+

+

+
+
+
+
+ + + + + + + + + +
+
+ + + + + +
+
+
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/dependency.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/dependency.html new file mode 100644 index 0000000..05b4312 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/dependency.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donut.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donut.html new file mode 100644 index 0000000..8ac1af3 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donut.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + +
+ +
+ + + + +
+ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutcharts.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutcharts.html new file mode 100644 index 0000000..cc9471b --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutcharts.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + + + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutchartssimple.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/README.md b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/dashboard.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/graphs.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + +
+
+
+
+

CodeMR Software Graphs

+

Click on the titles below to enlarge graphs

+ +
+ +
+ +
+ + +
+ +
+ +
+
+ +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ +
+
+
+
+
+
+

Object-Oriented Metric Descriptions

+

Informative only

+
+ +
+ + +
+
+
+ +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/notifications.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+
+
+

Notifications

+

Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

+ +
+
+
+
+
Notifications Style
+
+ This is a plain notification +
+
+ + This is a notification with close button. +
+
+ + + This is a notification with close button and icon. +
+
+ + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
+
+
+
Notification states
+
+ + Info - This is a regular notification made with ".alert-info" +
+
+ + Success - This is a regular notification made with ".alert-success" +
+
+ + Warning - This is a regular notification made with ".alert-warning" +
+
+ + Danger - This is a regular notification made with ".alert-danger" +
+
+
+
+
+
+
+
+
Notifications Places +

Click to view notifications

+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+ + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/table.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+ +
+
+

Detailed metric tables

+ +
+
+
+
+ +
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+
+
+ +
+
+ +
+
+
+ +
+
+
+ +

+ +

+ +
+
+ + + +
+ +
+
+
+ +
+
+
+ +

+ +

+ +
+
+ + + +
+ +
+
+
+ +
+
+
+ +

+ +

+ +
+
+ + + +
+ +
+
+
+
+
+
+ +

+ +

+ +
+
+ + + +
+ +
+
+
+
+
+
+ +

+ +

+ +
+
+ + + +
+ +
+
+
+ + + + +
+
+
+ + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/template.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +
+ + + +
+
+
+ +
+
+
+ + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartmethod.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
+ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartpackage.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartx.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
+ + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..3f2a18e --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-core working set: {serialx-core}", "Number of Highly Problematic Classes":0, "Number of Entities":29, "Number of Problematic Classes":4, "Class Lines of Code":2340, "Number of External Packages":7, "Number of Packages":5, "Number of External Entities":74} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..edfbc0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js @@ -0,0 +1,17 @@ +var matrix = [[0,1,8,1,1],[0,0,2,2,0],[1,0,0,1,0],[3,3,3,0,0],[0,0,0,0,0]] +var packages = [{ +"name": " org.ugp.serialx.converters", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.protocols", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.utils", "color": " #9ecae1" +} +,{ +"name": " org.ugp.serialx", "color": " #c6dbef" +} +,{ +"name": " org.ugp.serialx.converters.imports", "color": " #e6550d" +} +]; diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/summary_data.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..3937ccb --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 1244,count:4}, +{label:"fair quality attributes", color: "#007F24", value: 1315,count:25}]; diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..35f59bd --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,226 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-core working set: {serialx-core}", "value":2340, +"prmetrics":{"5":1,"6":1,"7":1,"8":2,"9":1,"10":1,"11":1}, +"prmetricvalues":{"5":0,"6":29,"7":4,"8":2340,"9":7,"10":5,"11":74}, +"children": [ { +"name": "org.ugp.serialx.converters", "value":571, +"pmetrics":{"4":3,"12":2,"13":1,"14":2,"3":1,"1":2,"0":2,"6":3,"8":2,"2":2,"15":1,"16":2}, +"pmetricvalues":{"4":3,"12":8,"13":2,"14":10,"3":1,"1":2,"0":2,"17":0.166,"6":12,"18":0.167,"8":571,"19":0.667,"2":2,"15":4,"16":288}, +"children":[ +{ +"name": "ProtocolConverter","key": "y","value":157, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, +"metricvalues":{"20":7,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":7,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +}, +{ +"name": "SerializableBase64Converter","key": "B","value":37, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +}, +{ +"name": "DataParser","key": "E","value":117, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +}, +{ +"name": "CharacterConverter","key": "G","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "NumberConverter","key": "x","value":88, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +}, +{ +"name": "VariableParser","key": "D","value":42, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":5,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":5,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} +}, +{ +"name": "StringConverter","key": "m","value":51, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +}, +{ +"name": "DataConverter","key": "P","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +}, +{ +"name": "BooleanConverter","key": "Q","value":29, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +}, +{ +"name": "NullConverter","key": "L","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +} +] +},{ +"name": "org.ugp.serialx.protocols", "value":223, +"pmetrics":{"4":2,"12":1,"13":1,"14":2,"3":1,"1":1,"0":1,"6":2,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":3,"13":0,"14":7,"3":1,"1":1,"0":1,"17":0.428,"6":7,"18":0.143,"8":223,"19":0.429,"2":1,"15":4,"16":80}, +"children":[ +{ +"name": "EnumProtocol","key": "N","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "ScopeProtocol","key": "A","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +}, +{ +"name": "MapProtocol","key": "r","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +}, +{ +"name": "SerializationProtocol","key": "t","value":120, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, +"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +}, +{ +"name": "StringProtocol","key": "C","value":33, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +}, +{ +"name": "ListProtocol","key": "K","value":16, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +} +] +},{ +"name": "org.ugp.serialx.utils", "value":491, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":3,"16":2}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":3,"3":1,"1":2,"0":2,"17":0.929,"6":3,"18":0.0,"8":491,"19":0.071,"2":1,"15":13,"16":246}, +"children":[ +{ +"name": "LogProvider","key": "I","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "Registry","key": "O","value":125, +"metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +}, +{ +"name": "Utils","key": "w","value":346, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":1,"28":3,"29":5,"30":1,"31":1,"32":4,"33":1,"34":2,"35":3,"36":1,"16":5,"37":1,"4":3,"8":3,"2":1,"3":4,"1":5}, +"metricvalues":{"20":5,"21":0,"38":13,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"39":4,"33":5,"34":85,"40":9,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} +} +] +},{ +"name": "org.ugp.serialx", "value":923, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":3,"13":1,"14":3,"3":1,"1":2,"0":2,"17":0.071,"6":4,"18":0.5,"8":923,"19":0.429,"2":1,"15":4,"16":405}, +"children":[ +{ +"name": "GenericScope","key": "M","value":333, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, +"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +}, +{ +"name": "Scope","key": "s","value":353, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":1,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":1,"3":4,"1":5}, +"metricvalues":{"20":5,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":5,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} +}, +{ +"name": "MultimediaSerializer","key": "k","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +}, +{ +"name": "Serializer","key": "J","value":212, +"metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, +"metricvalues":{"20":8,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":8,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +} +] +},{ +"name": "org.ugp.serialx.converters.imports", "value":132, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":0,"13":1,"14":2,"3":1,"1":1,"0":1,"17":0.667,"6":3,"18":0.333,"8":132,"19":0.0,"2":1,"15":1,"16":49}, +"children":[ +{ +"name": "Import","key": "H","value":48, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, +"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +}, +{ +"name": "ImportsProvider","key": "o","value":84, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/table_data.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..9a55a0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#4)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1Scope ▄ ▄ ▄ ▄35317517349022Utils ▄ ▄ ▄ ▄3461881161013GenericScope ▄ ▄ ▄ ▄33313814460314Serializer ▄ ▄ ▄ ▄212792153433';var EQ_Table5_Title = 'List of all classes (#29)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1Serializer ▄ ▄ ▄ ▄212very-highlow-mediumvery-highmedium-high2ProtocolConverter ▄ ▄ ▄ ▄157medium-highlow-mediummedium-highlow-medium3Scope ▄ ▄ ▄ ▄353very-highlowhighhigh4Utils ▄ ▄ ▄ ▄346very-highlowhighmedium-high5GenericScope ▄ ▄ ▄ ▄333very-highlowvery-highvery-high6Registry ▄ ▄ ▄ ▄125medium-highlowlow-mediumlow-medium7NumberConverter ▄ ▄ ▄ ▄88low-mediumlowlow-mediumlow-medium8StringConverter ▄ ▄ ▄ ▄51low-mediumlowlow-mediumlow-medium9VariableParser ▄ ▄ ▄ ▄42low-mediumlowlowlow10StringProtocol ▄ ▄ ▄ ▄33low-mediumlowlowlow11MapProtocol ▄ ▄ ▄ ▄25low-mediumlowlowlow12ScopeProtocol ▄ ▄ ▄ ▄17low-mediumlowlowlow13ListProtocol ▄ ▄ ▄ ▄16low-mediumlowlowlow14EnumProtocol ▄ ▄ ▄ ▄12low-mediumlowlowlow15SerializationProt... ▄ ▄ ▄ ▄120lowlowmedium-highlow-medium16DataParser ▄ ▄ ▄ ▄117lowlowlowlow-medium17ParserRegistry ▄ ▄ ▄ ▄110lowlowlowlow18ImportsProvider ▄ ▄ ▄ ▄84lowlowlowlow-medium19ProtocolRegistry ▄ ▄ ▄ ▄57lowlowlowlow20Imports ▄ ▄ ▄ ▄51lowlowlowlow21Import ▄ ▄ ▄ ▄48lowlowlow-mediumlow22SerializableBase6... ▄ ▄ ▄ ▄37lowlowlowlow23BooleanConverter ▄ ▄ ▄ ▄29lowlowlowlow24MultimediaSerializer ▄ ▄ ▄ ▄25lowlowmedium-highlow25CharacterConverter ▄ ▄ ▄ ▄20lowlowlowlow26LogProvider ▄ ▄ ▄ ▄20lowlowlowlow27NullConverter ▄ ▄ ▄ ▄17lowlowlowlow28DataConverter ▄ ▄ ▄ ▄13lowlowlowlow29IsSelectorScope ▄ ▄ ▄ ▄1lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/report.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

Distribution of Quality Attributes

+ +
+ +

Metric Values in Sunburst Chart

+ +
+ +

Metric Values by Packages

+ +
+ +

Metric Values in Treemap Chart

+ +
+ +

Package Dependencies

+ + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/reportforprint.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

Distribution of Quality Attributes

+ +
+ +

Metric Values in Sunburst Chart

+ +
+ +

Metric Values by Packages

+ +
+ +

Metric Values in Treemap Chart

+ +
+ +

Package Dependencies

+ + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/sunburst.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
+
+

+

+

+
+
+
+
+ + + + + + + + + + + + + + +
+
+ + + +
+
+ + + +
+
+ + + +
+
+
+
+ +
+
+
+ + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/treemap.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
+ + +
+ +
+ + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/index.html b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/animate.min.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/animate.min.css new file mode 100644 index 0000000..0b6a47d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/animate.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license - http://opensource.org/licenses/MIT + +Copyright (c) 2015 Daniel Eden +*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}@keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}100%{opacity:1}}@keyframes fadeIn{from{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}100%{opacity:0}}@keyframes fadeOut{from{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/bootstrap.min.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/bootstrap.min.css new file mode 100644 index 0000000..d65c66b --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;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:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;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,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/demo.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/demo.css new file mode 100644 index 0000000..febe628 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/demo.css @@ -0,0 +1,61 @@ +@media (min-width: 992px){ + .typo-line{ + padding-left: 140px; + margin-bottom: 40px; + position: relative; + } + + .typo-line .category{ + transform: translateY(-50%); + top: 50%; + left: 0px; + position: absolute; + } +} + +.all-icons [class*="pe-"]{ + font-size: 40px; +} +.all-icons input{ + border: 0; +} +.all-icons .font-icon-detail{ + text-align: center; + padding: 45px 0px 30px; + border: 1px solid #e5e5e5; + border-radius: 6px; + margin: 15px 0; +} +.all-icons .font-icon-detail input{ + margin: 25px auto 0; + width: 100%; + text-align: center; + display: block; + color: #aaa; + font-size: 13px; +} + +#map{ + position:relative; + width:100%; + height: calc(100% - 60px); +} + +.places-buttons .btn{ + margin-bottom: 30px +} +.sidebar .nav > li.active-pro{ + position: absolute; + width: 100%; + bottom: 10px; +} +.sidebar .nav > li.active-pro a{ + background: rgba(255, 255, 255, 0.14); + opacity: 1; + color: #FFFFFF; +} + +.table-upgrade td:nth-child(2), +.table-upgrade td:nth-child(3){ + text-align: center; +} diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/font-awesome.min.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/helptip.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/helptip.css new file mode 100644 index 0000000..8cca39a --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/helptip.css @@ -0,0 +1,148 @@ + +/*------------------------- + Inline help tip +--------------------------*/ + +.help-tip{ + position: relative; + top: 4px; + left: 0px; + text-align: center; + border-radius: 10%; + width: 48px; + height: 24px; + font-size: 14px; + line-height: 26px; + cursor: default; +} + + +.help-tip:before{ + content: url(../img/help.png); + font-weight: bold; + color:#fff; +} + +.help-tip:hover div{ + display:block; + transform-origin: 100% 0%; + + -webkit-animation: fadeIn 0.3s ease-in-out; + animation: fadeIn 0.3s ease-in-out; + +} + +.help-tip div{ + display: none; + text-align: left; + background-color: white; + padding: 20px; + width: 300px; + position: absolute; + border-radius: 3px; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + left: -100px; + color: black; + font-size: 13px; + line-height: 1.4; +} + +/* arrow */ +.help-tip div:before{ + position: absolute; + content: ''; + width:0; + height: 0; + border:6px solid transparent; + border-bottom-color: white; + left:100px; + top:-12px; + +} + +.help-tip div:after{ + width:100%; + height:40px; + content:''; + position: absolute; + top:-40px; + left:0; +} + + +@-webkit-keyframes fadeIn { + 0% { + opacity:0; + transform: scale(0.6); + } + + 100% { + opacity:100%; + transform: scale(1); + } +} + +@keyframes fadeIn { + 0% { opacity:0; } + 100% { opacity:100%; } +} + + + +@media (max-width: 1024px) { + #bsaHolder, footer{ display:none;} +} + + .tip-legend .legend-title { + text-align: left; + margin-bottom: 5px; + font-weight: bold; + font-size: 90%; + } + .tip-legend ul { + margin: 0; + margin-bottom: 5px; + padding: 0; + float: left; + list-style: none; + } + .tip-legend ul li { + font-size: 80%; + list-style: lower-roman; + margin-left:25px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li { + + font-size: 80%; + list-style: none; + margin-left: 0px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li span { + + float: left; + height: 16px; + width: 30px; + margin-right: 5px; + margin-left:0px; + border: 1px solid #999; + } + .tip-legend .tip-metric-source { + font-size: 90%; + color: #999; + clear: both; + } + .tip-legend a { + color: #777; + } + + .tip-subsection { + text-align: left; + margin-bottom: 5px; + font-size: 90%; + } \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/light-bootstrap-dashboard.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/light-bootstrap-dashboard.css new file mode 100644 index 0000000..3ce28f5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/light-bootstrap-dashboard.css @@ -0,0 +1,3393 @@ +/* light colors */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } +} +@-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(360deg); + } +} +@-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + } +} +/* Font Smoothing */ +body, +h1, .h1, +h2, .h2, +h3, .h3, +h4, .h4, +h5, .h5, +h6, .h6, +p, +.navbar, +.brand, +.btn-simple, +.alert, +a, +.td-name, +td, +button.close { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-family: "Roboto","Helvetica Neue",Arial,sans-serif; + font-weight: 400; +} + +h1, .h1, h2, .h2, h3, .h3, h4, .h4 { + font-weight: 300; + margin: 30px 0 15px; +} + +h1, .h1 { + font-size: 52px; +} + +h2, .h2 { + font-size: 36px; +} + +h3, .h3 { + font-size: 28px; + margin: 20px 0 10px; +} + +h4, .h4 { + font-size: 22px; + line-height: 30px; +} + +h5, .h5 { + font-size: 16px; + margin-bottom: 15px; +} + +h6, .h6 { + font-size: 14px; + font-weight: 600; + text-transform: uppercase; +} + +p { + font-size: 16px; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #9A9A9A; + font-weight: 300; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 60%; +} + +h1 .subtitle { + display: block; + margin: 0 0 30px; +} + +.text-muted { + color: #9A9A9A; +} + +.text-primary, .text-primary:hover { + color: #1D62F0 !important; +} + +.text-info, .text-info:hover { + color: #1DC7EA !important; +} + +.text-success, .text-success:hover { + color: #87CB16 !important; +} + +.text-warning, .text-warning:hover { + color: #FF9500 !important; +} + +.text-danger, .text-danger:hover { + color: #FF4A55 !important; +} + +/* General overwrite */ +body, +.wrapper { + min-height: 100vh; + position: relative; +} + +a { + color: #1DC7EA; +} +a:hover, a:focus { + color: #42d0ed; + text-decoration: none; +} + +a:focus, a:active, +button::-moz-focus-inner, +input::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +select::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + outline: 0; +} + +.ui-slider-handle:focus, +.navbar-toggle, +input:focus { + outline: 0 !important; +} + +/* Animations */ +.form-control, +.input-group-addon, +.tagsinput, +.navbar, +.navbar .alert { + -webkit-transition: all 300ms linear; + -moz-transition: all 300ms linear; + -o-transition: all 300ms linear; + -ms-transition: all 300ms linear; + transition: all 300ms linear; +} + +.sidebar .nav a, +.table > tbody > tr .td-actions .btn { + -webkit-transition: all 150ms ease-in; + -moz-transition: all 150ms ease-in; + -o-transition: all 150ms ease-in; + -ms-transition: all 150ms ease-in; + transition: all 150ms ease-in; +} + +.btn { + -webkit-transition: all 100ms ease-in; + -moz-transition: all 100ms ease-in; + -o-transition: all 100ms ease-in; + -ms-transition: all 100ms ease-in; + transition: all 100ms ease-in; +} + +.fa { + width: 18px; + text-align: center; +} + +.margin-top { + margin-top: 50px; +} + +.wrapper { + position: relative; + top: 0; + height: 100vh; +} + +.sidebar { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 260px; + display: block; + z-index: 1; + color: #fff; + font-weight: 200; + background-size: cover; + background-position: center center; +} +.sidebar .sidebar-wrapper { + position: relative; + max-height: none; + min-height: 100%; + overflow: hidden; + width: 260px; + z-index: 4; +} +.sidebar .sidebar-background { + position: absolute; + z-index: 1; + height: 100%; + width: 100%; + display: block; + top: 0; + left: 0; + background-size: cover; + background-position: center center; +} +.sidebar .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar .nav { + margin-top: 20px; +} +.sidebar .nav li > a { + color: #FFFFFF; + margin: 5px 15px; + opacity: .86; + border-radius: 4px; +} +.sidebar .nav li:hover > a { + background: rgba(255, 255, 255, 0.13); + opacity: 1; +} +.sidebar .nav li.active > a { + color: #FFFFFF; + opacity: 1; + background: rgba(255, 255, 255, 0.23); +} +.sidebar .nav p { + margin: 0; + line-height: 30px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.sidebar .nav i { + font-size: 28px; + float: left; + margin-right: 15px; + line-height: 30px; + width: 30px; + text-align: center; +} + +.sidebar .logo, +body > .navbar-collapse .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p, +body > .navbar-collapse .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text, +body > .navbar-collapse .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim, +body > .navbar-collapse .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img, +body > .navbar-collapse .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar:after, .sidebar:before, +body > .navbar-collapse:after, +body > .navbar-collapse:before { + display: block; + content: ""; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +.sidebar:before, +body > .navbar-collapse:before { + opacity: .33; + background: #000000; +} +.sidebar:after, +body > .navbar-collapse:after { + background: #787878; + background: -moz-linear-gradient(top, #787878 0%, #343434 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #787878), color-stop(100%, #343434)); + background: -webkit-linear-gradient(top, #787878 0%, #343434 100%); + background: -o-linear-gradient(top, #787878 0%, #343434 100%); + background: -ms-linear-gradient(top, #787878 0%, #343434 100%); + background: linear-gradient(to bottom, #787878 0%, #343434 100%); + background-size: 150% 150%; + z-index: 3; + opacity: 1; +} +.sidebar[data-image]:after, .sidebar.has-image:after, +body > .navbar-collapse[data-image]:after, +body > .navbar-collapse.has-image:after { + opacity: .77; +} +.sidebar[data-color="blue"]:after, +body > .navbar-collapse[data-color="blue"]:after { + background: #1F77D0; + background: -moz-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1F77D0), color-stop(100%, #533ce1)); + background: -webkit-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -o-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -ms-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: linear-gradient(to bottom, #1F77D0 0%, #533ce1 100%); + background-size: 150% 150%; +} +.sidebar[data-color="azure"]:after, +body > .navbar-collapse[data-color="azure"]:after { + background: #1DC7EA; + background: -moz-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1DC7EA), color-stop(100%, #4091ff)); + background: -webkit-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -o-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -ms-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: linear-gradient(to bottom, #1DC7EA 0%, #4091ff 100%); + background-size: 150% 150%; +} +.sidebar[data-color="green"]:after, +body > .navbar-collapse[data-color="green"]:after { + background: #87CB16; + background: -moz-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #87CB16), color-stop(100%, #6dc030)); + background: -webkit-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -o-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -ms-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: linear-gradient(to bottom, #87CB16 0%, #6dc030 100%); + background-size: 150% 150%; +} +.sidebar[data-color="orange"]:after, +body > .navbar-collapse[data-color="orange"]:after { + background: #FFA534; + background: -moz-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FFA534), color-stop(100%, #ff5221)); + background: -webkit-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -o-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -ms-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: linear-gradient(to bottom, #FFA534 0%, #ff5221 100%); + background-size: 150% 150%; +} +.sidebar[data-color="red"]:after, +body > .navbar-collapse[data-color="red"]:after { + background: #FB404B; + background: -moz-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FB404B), color-stop(100%, #bb0502)); + background: -webkit-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -o-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -ms-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: linear-gradient(to bottom, #FB404B 0%, #bb0502 100%); + background-size: 150% 150%; +} +.sidebar[data-color="purple"]:after, +body > .navbar-collapse[data-color="purple"]:after { + background: #9368E9; + background: -moz-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9368E9), color-stop(100%, #943bea)); + background: -webkit-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -o-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -ms-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: linear-gradient(to bottom, #9368E9 0%, #943bea 100%); + background-size: 150% 150%; +} + +.main-panel { + background: rgba(203, 203, 210, 0.15); + position: relative; + z-index: 2; + float: right; + width: calc(100% - 260px); + min-height: 100%; +} +.main-panel > .content { + padding: 30px 15px; + min-height: calc(100% - 123px); +} +.main-panel > .footer { + border-top: 1px solid #e7e7e7; +} +.main-panel .navbar { + margin-bottom: 0; +} + +.sidebar, +.main-panel { + overflow: auto; + max-height: 100%; + height: 100%; + -webkit-transition-property: top,bottom; + transition-property: top,bottom; + -webkit-transition-duration: .2s,.2s; + transition-duration: .2s,.2s; + -webkit-transition-timing-function: linear,linear; + transition-timing-function: linear,linear; + -webkit-overflow-scrolling: touch; +} + +.btn { + border-width: 2px; + background-color: transparent; + font-weight: 400; + opacity: 0.8; + filter: alpha(opacity=80); + padding: 8px 16px; + border-color: #888888; + color: #888888; +} +.btn:hover, .btn:focus, .btn:active, .btn.active, .open > .btn.dropdown-toggle { + background-color: transparent; + color: #777777; + border-color: #777777; +} +.btn.disabled, .btn.disabled:hover, .btn.disabled:focus, .btn.disabled.focus, .btn.disabled:active, .btn.disabled.active, .btn:disabled, .btn:disabled:hover, .btn:disabled:focus, .btn:disabled.focus, .btn:disabled:active, .btn:disabled.active, .btn[disabled], .btn[disabled]:hover, .btn[disabled]:focus, .btn[disabled].focus, .btn[disabled]:active, .btn[disabled].active, fieldset[disabled] .btn, fieldset[disabled] .btn:hover, fieldset[disabled] .btn:focus, fieldset[disabled] .btn.focus, fieldset[disabled] .btn:active, fieldset[disabled] .btn.active { + background-color: transparent; + border-color: #888888; +} +.btn.btn-fill { + color: #FFFFFF; + background-color: #888888; + opacity: 1; + filter: alpha(opacity=100); +} +.btn.btn-fill:hover, .btn.btn-fill:focus, .btn.btn-fill:active, .btn.btn-fill.active, .open > .btn.btn-fill.dropdown-toggle { + background-color: #777777; + color: #FFFFFF; +} +.btn.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn .caret { + border-top-color: #888888; +} +.btn:hover, .btn:focus { + opacity: 1; + filter: alpha(opacity=100); + outline: 0 !important; +} +.btn:active, .btn.active, .open > .btn.dropdown-toggle { + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; +} +.btn.btn-icon { + padding: 8px; +} + +.btn-primary { + border-color: #3472F7; + color: #3472F7; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { + background-color: transparent; + color: #1D62F0; + border-color: #1D62F0; +} +.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary:disabled, .btn-primary:disabled:hover, .btn-primary:disabled:focus, .btn-primary:disabled.focus, .btn-primary:disabled:active, .btn-primary:disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active { + background-color: transparent; + border-color: #3472F7; +} +.btn-primary.btn-fill { + color: #FFFFFF; + background-color: #3472F7; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary.btn-fill:hover, .btn-primary.btn-fill:focus, .btn-primary.btn-fill:active, .btn-primary.btn-fill.active, .open > .btn-primary.btn-fill.dropdown-toggle { + background-color: #1D62F0; + color: #FFFFFF; +} +.btn-primary.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-primary .caret { + border-top-color: #3472F7; +} + +.btn-success { + border-color: #87CB16; + color: #87CB16; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { + background-color: transparent; + color: #049F0C; + border-color: #049F0C; +} +.btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success:disabled, .btn-success:disabled:hover, .btn-success:disabled:focus, .btn-success:disabled.focus, .btn-success:disabled:active, .btn-success:disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled].active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active { + background-color: transparent; + border-color: #87CB16; +} +.btn-success.btn-fill { + color: #FFFFFF; + background-color: #87CB16; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-success.btn-fill:hover, .btn-success.btn-fill:focus, .btn-success.btn-fill:active, .btn-success.btn-fill.active, .open > .btn-success.btn-fill.dropdown-toggle { + background-color: #049F0C; + color: #FFFFFF; +} +.btn-success.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-success .caret { + border-top-color: #87CB16; +} + +.btn-info { + border-color: #1DC7EA; + color: #1DC7EA; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { + background-color: transparent; + color: #42d0ed; + border-color: #42d0ed; +} +.btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info:disabled, .btn-info:disabled:hover, .btn-info:disabled:focus, .btn-info:disabled.focus, .btn-info:disabled:active, .btn-info:disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled].active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active { + background-color: transparent; + border-color: #1DC7EA; +} +.btn-info.btn-fill { + color: #FFFFFF; + background-color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-info.btn-fill:hover, .btn-info.btn-fill:focus, .btn-info.btn-fill:active, .btn-info.btn-fill.active, .open > .btn-info.btn-fill.dropdown-toggle { + background-color: #42d0ed; + color: #FFFFFF; +} +.btn-info.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-info .caret { + border-top-color: #1DC7EA; +} + +.btn-warning { + border-color: #FF9500; + color: #FF9500; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + background-color: transparent; + color: #ED8D00; + border-color: #ED8D00; +} +.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning:disabled, .btn-warning:disabled:hover, .btn-warning:disabled:focus, .btn-warning:disabled.focus, .btn-warning:disabled:active, .btn-warning:disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active { + background-color: transparent; + border-color: #FF9500; +} +.btn-warning.btn-fill { + color: #FFFFFF; + background-color: #FF9500; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-warning.btn-fill:hover, .btn-warning.btn-fill:focus, .btn-warning.btn-fill:active, .btn-warning.btn-fill.active, .open > .btn-warning.btn-fill.dropdown-toggle { + background-color: #ED8D00; + color: #FFFFFF; +} +.btn-warning.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-warning .caret { + border-top-color: #FF9500; +} + +.btn-danger { + border-color: #FF4A55; + color: #FF4A55; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { + background-color: transparent; + color: #EE2D20; + border-color: #EE2D20; +} +.btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger:disabled, .btn-danger:disabled:hover, .btn-danger:disabled:focus, .btn-danger:disabled.focus, .btn-danger:disabled:active, .btn-danger:disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active { + background-color: transparent; + border-color: #FF4A55; +} +.btn-danger.btn-fill { + color: #FFFFFF; + background-color: #FF4A55; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-danger.btn-fill:hover, .btn-danger.btn-fill:focus, .btn-danger.btn-fill:active, .btn-danger.btn-fill.active, .open > .btn-danger.btn-fill.dropdown-toggle { + background-color: #EE2D20; + color: #FFFFFF; +} +.btn-danger.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-danger .caret { + border-top-color: #FF4A55; +} + +.btn-neutral { + border-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral:hover, .btn-neutral:focus, .btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: transparent; + color: #FFFFFF; + border-color: #FFFFFF; +} +.btn-neutral.disabled, .btn-neutral.disabled:hover, .btn-neutral.disabled:focus, .btn-neutral.disabled.focus, .btn-neutral.disabled:active, .btn-neutral.disabled.active, .btn-neutral:disabled, .btn-neutral:disabled:hover, .btn-neutral:disabled:focus, .btn-neutral:disabled.focus, .btn-neutral:disabled:active, .btn-neutral:disabled.active, .btn-neutral[disabled], .btn-neutral[disabled]:hover, .btn-neutral[disabled]:focus, .btn-neutral[disabled].focus, .btn-neutral[disabled]:active, .btn-neutral[disabled].active, fieldset[disabled] .btn-neutral, fieldset[disabled] .btn-neutral:hover, fieldset[disabled] .btn-neutral:focus, fieldset[disabled] .btn-neutral.focus, fieldset[disabled] .btn-neutral:active, fieldset[disabled] .btn-neutral.active { + background-color: transparent; + border-color: #FFFFFF; +} +.btn-neutral.btn-fill { + color: #FFFFFF; + background-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus, .btn-neutral.btn-fill:active, .btn-neutral.btn-fill.active, .open > .btn-neutral.btn-fill.dropdown-toggle { + background-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-neutral .caret { + border-top-color: #FFFFFF; +} +.btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: #FFFFFF; + color: #888888; +} +.btn-neutral.btn-fill, .btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus { + color: #888888; +} +.btn-neutral.btn-simple:active, .btn-neutral.btn-simple.active { + background-color: transparent; +} + +.btn:disabled, .btn[disabled], .btn.disabled { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.btn-round { + border-width: 1px; + border-radius: 30px !important; + padding: 9px 18px; +} +.btn-round.btn-icon { + padding: 9px; +} + +.btn-simple { + border: 0; + font-size: 16px; + padding: 8px 16px; +} +.btn-simple.btn-icon { + padding: 8px; +} + +.btn-lg { + font-size: 18px; + border-radius: 6px; + padding: 14px 30px; + font-weight: 400; +} +.btn-lg.btn-round { + padding: 15px 30px; +} +.btn-lg.btn-simple { + padding: 16px 30px; +} + +.btn-sm { + font-size: 12px; + border-radius: 3px; + padding: 5px 10px; +} +.btn-sm.btn-round { + padding: 6px 10px; +} +.btn-sm.btn-simple { + padding: 7px 10px; +} + +.btn-xs { + font-size: 12px; + border-radius: 3px; + padding: 1px 5px; +} +.btn-xs.btn-round { + padding: 2px 5px; +} +.btn-xs.btn-simple { + padding: 3px 5px; +} + +.btn-wd { + min-width: 140px; +} + +.btn-group.select { + width: 100%; +} + +.btn-group.select .btn { + text-align: left; +} + +.btn-group.select .caret { + position: absolute; + top: 50%; + margin-top: -1px; + right: 8px; +} + +.form-control::-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control::-webkit-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-ms-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; + color: #565656; + padding: 8px 12px; + height: 40px; + -webkit-box-shadow: none; + box-shadow: none; +} +.form-control:focus { + background-color: #FFFFFF; + border: 1px solid #AAAAAA; + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; + color: #333333; +} +.has-success .form-control, .has-error .form-control, .has-success .form-control:focus, .has-error .form-control:focus { + border-color: #E3E3E3; + -webkit-box-shadow: none; + box-shadow: none; +} +.has-success .form-control { + color: #87CB16; +} +.has-success .form-control:focus { + border-color: #87CB16; +} +.has-error .form-control { + color: #FF4A55; +} +.has-error .form-control:focus { + border-color: #FF4A55; +} +.form-control + .form-control-feedback { + border-radius: 6px; + font-size: 14px; + margin-top: -7px; + position: absolute; + right: 10px; + top: 50%; + vertical-align: middle; +} +.open .form-control { + border-radius: 4px 4px 0 0; + border-bottom-color: transparent; +} + +.input-lg { + height: 55px; + padding: 14px 30px; +} + +.has-error .form-control-feedback { + color: #FF4A55; +} + +.has-success .form-control-feedback { + color: #87CB16; +} + +.input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; +} +.has-success .input-group-addon, .has-error .input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; +} +.has-error .form-control:focus + .input-group-addon { + border-color: #FF4A55; + color: #FF4A55; +} +.has-success .form-control:focus + .input-group-addon { + border-color: #87CB16; + color: #87CB16; +} +.form-control:focus + .input-group-addon, .form-control:focus ~ .input-group-addon { + background-color: #FFFFFF; + border-color: #9A9A9A; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-right: 0 none; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-left: 0 none; +} + +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + background-color: #F5F5F5; + color: #888888; + cursor: not-allowed; +} + +.input-group-btn .btn { + border-width: 1px; + padding: 9px 16px; +} + +.input-group-btn .btn-default:not(.btn-fill) { + border-color: #DDDDDD; +} + +.input-group-btn:last-child > .btn { + margin-left: 0; +} + +.input-group-focus .input-group-addon { + border-color: #9A9A9A; +} + +.alert { + border: 0; + border-radius: 0; + color: #FFFFFF; + padding: 10px 15px; + font-size: 14px; +} +.container .alert { + border-radius: 4px; +} +.navbar .alert { + border-radius: 0; + left: 0; + position: absolute; + right: 0; + top: 85px; + width: 100%; + z-index: 3; +} +.navbar:not(.navbar-transparent) .alert { + top: 70px; +} +.alert span[data-notify="icon"] { + font-size: 30px; + display: block; + left: 15px; + position: absolute; + top: 50%; + margin-top: -15px; +} +.alert button.close { + position: absolute; + right: 10px; + top: 50%; + margin-top: -13px; + z-index: 1033; + background-color: #FFFFFF; + display: block; + border-radius: 50%; + opacity: .4; + line-height: 11px; + width: 25px; + height: 25px; + outline: 0 !important; + text-align: center; + padding: 3px; + font-weight: 300; +} +.alert button.close:hover { + opacity: .55; +} +.alert .close ~ span { + display: block; + max-width: 89%; +} +.alert[data-notify="container"] { + padding: 10px 10px 10px 20px; + border-radius: 4px; +} +.alert.alert-with-icon { + padding-left: 65px; +} + +.alert-info { + background-color: #63d8f1; +} + +.alert-success { + background-color: #a1e82c; +} + +.alert-warning { + background-color: #ffbc67; +} + +.alert-danger { + background-color: #fc727a; +} + +.table .radio, +.table .checkbox { + position: relative; + height: 20px; + display: block; + width: 20px; + padding: 0px 0px; + margin: 0px 5px; + text-align: center; +} +.table .radio .icons, +.table .checkbox .icons { + left: 5px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 12px 8px; + vertical-align: middle; +} +.table > thead > tr > th { + border-bottom-width: 1px; + font-size: 12px; + text-transform: uppercase; + color: #9A9A9A; + font-weight: 400; + padding-bottom: 5px; +} +.table .td-actions .btn { + opacity: 0.36; + filter: alpha(opacity=36); +} +.table .td-actions .btn.btn-xs { + padding-left: 3px; + padding-right: 3px; +} +.table .td-actions { + min-width: 90px; +} +.table > tbody > tr { + position: relative; +} +.table > tbody > tr:hover .td-actions .btn { + opacity: 1; + filter: alpha(opacity=100); +} + +/* Checkbox and radio */ +.checkbox, +.radio { + margin-bottom: 12px; + padding-left: 32px; + position: relative; + -webkit-transition: color 0.25s linear; + transition: color 0.25s linear; + font-size: 14px; + font-weight: normal; + line-height: 1.5; + color: #333333; +} + +.checkbox input, +.radio input { + outline: none !important; + display: none; +} + +.checkbox .icons, +.radio .icons { + color: #DDDDDD; + display: block; + height: 20px; + left: 0; + position: absolute; + top: 0; + width: 20px; + text-align: center; + line-height: 21px; + font-size: 20px; + cursor: pointer; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox .icons .first-icon, +.radio .icons .first-icon, +.checkbox .icons .second-icon, +.radio .icons .second-icon { + display: inline-table; + position: absolute; + left: 0; + top: 0; + background-color: transparent; + margin: 0; + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox .icons .second-icon, +.radio .icons .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover, +.radio:hover { + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox:hover .first-icon, +.radio:hover .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover .second-icon, +.radio:hover .second-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.checked, +.radio.checked { + color: #1DC7EA; +} + +.checkbox.checked .first-icon, +.radio.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.checked .second-icon, +.radio.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #1DC7EA; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox.disabled, +.radio.disabled { + cursor: default; + color: #DDDDDD !important; +} + +.checkbox.disabled .icons, +.radio.disabled .icons { + color: #DDDDDD !important; +} + +.checkbox.disabled .first-icon, +.radio.disabled .first-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.disabled .second-icon, +.radio.disabled .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .icons, +.radio.disabled.checked .icons { + color: #DDDDDD; +} + +.checkbox.disabled.checked .first-icon, +.radio.disabled.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .second-icon, +.radio.disabled.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #D9D9D9; +} + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ +.has-switch { + border-radius: 30px; + cursor: pointer; + display: inline-block; + line-height: 1.72222; + overflow: hidden; + position: relative; + text-align: left; + width: 60px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + /* this code is for fixing safari bug with hidden overflow for border-radius */ + -webkit-mask: url("../img/mask.png") 0 0 no-repeat; + -webkit-mask-size: 60px 24px; + mask: url("../img/mask.png") 0 0 no-repeat; +} + +.has-switch.deactivate { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} + +.has-switch.deactivate label, +.has-switch.deactivate span { + cursor: default !important; +} + +.has-switch > div { + position: relative; + top: 0; + width: 100px; +} + +.has-switch > div.switch-animate { + -webkit-transition: left 0.25s ease-out; + transition: left 0.25s ease-out; +} + +.has-switch > div.switch-off { + left: -35px; +} + +.has-switch > div.switch-on { + left: 0; +} + +.has-switch > div label { + background-color: #FFFFFF; + background: white; + background: -moz-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #f1f1f2)); + background: -webkit-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -o-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -ms-linear-gradient(top, white 0%, #f1f1f2 100%); + background: linear-gradient(to bottom, white 0%, #f1f1f2 100%); + background-size: 150% 150%; + box-shadow: 0 1px 1px #FFFFFF inset, 0 1px 1px rgba(0, 0, 0, 0.25); + cursor: pointer; +} + +.has-switch input[type=checkbox] { + display: none; +} + +.has-switch span { + /* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) inset; */ + cursor: pointer; + float: left; + font-size: 11px; + font-weight: 400; + height: 24px; + line-height: 15px; + margin: 0; + padding-bottom: 6px; + padding-top: 5px; + position: relative; + text-align: center; + text-indent: -10px; + width: 50%; + z-index: 1; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch span.switch-left { + background-color: #1DC7EA; + border-left: 1px solid transparent; + border-radius: 30px 0 0 30px; + color: #FFFFFF; +} + +.has-switch .switch-off span.switch-left { + background-color: #DDDDDD; +} + +.has-switch span.switch-right { + border-radius: 0 30px 30px 0; + background-color: #1DC7EA; + color: #ffffff; + text-indent: 1px; +} + +.has-switch .switch-off span.switch-right { + background-color: #DDDDDD; +} + +.has-switch label { + border-radius: 12px; + float: left; + height: 22px; + margin: 1px -13px; + padding: 0; + position: relative; + transition: all 0.25s ease-out 0s; + vertical-align: middle; + width: 22px; + z-index: 100; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch .switch-on .fa-check:before { + margin-left: 10px; +} + +.has-switch:hover .switch-on label { + margin: 1px -17px; + width: 26px; +} + +.has-switch:hover .switch-off label { + margin: 1px -13px; + width: 26px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: transparent; +} + +.navbar { + border: 0; + font-size: 16px; + border-radius: 0; +} +.navbar .navbar-brand { + font-weight: 400; + margin: 5px 0px; + padding: 15px 15px; + font-size: 20px; +} +.navbar .navbar-nav > li > a { + padding: 10px 15px; + margin: 10px 3px; + position: relative; +} +.navbar .navbar-nav > li > a.btn { + margin: 15px 3px; + padding: 8px 16px; +} +.navbar .navbar-nav > li > a.btn-round { + margin: 16px 3px; +} +.navbar .navbar-nav > li > a [class^="fa"] { + font-size: 19px; + position: relative; + line-height: 16px; + top: 1px; +} +.navbar .navbar-nav .notification { + position: absolute; + background-color: #FB404B; + text-align: center; + border-radius: 10px; + min-width: 18px; + padding: 0 5px; + height: 18px; + font-size: 12px; + color: #FFFFFF; + font-weight: bold; + line-height: 18px; + top: 0px; + left: 7px; +} +.navbar .btn { + margin: 15px 3px; + font-size: 14px; +} +.navbar .btn-simple { + font-size: 16px; +} +.navbar.fixed { + width: calc(100% - $sidebar-width); + right: 0; + left: auto; + border-radius: 0; +} + +.navbar-nav > li > .dropdown-menu { + border-radius: 10px; + margin-top: -5px; +} + +.navbar-transparent .navbar-brand, [class*="navbar-ct"] .navbar-brand { + color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .navbar-brand:focus, .navbar-transparent .navbar-brand:hover, [class*="navbar-ct"] .navbar-brand:focus, [class*="navbar-ct"] .navbar-brand:hover { + background-color: transparent; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav > li > a:not(.btn), [class*="navbar-ct"] .navbar-nav > li > a:not(.btn) { + color: #FFFFFF; + border-color: #FFFFFF; + opacity: 0.8; + filter: alpha(opacity=80); +} +.navbar-transparent .navbar-nav > .active > a:not(.btn), +.navbar-transparent .navbar-nav > .active > a:hover:not(.btn), +.navbar-transparent .navbar-nav > .active > a:focus:not(.btn), +.navbar-transparent .navbar-nav > li > a:hover:not(.btn), +.navbar-transparent .navbar-nav > li > a:focus:not(.btn), [class*="navbar-ct"] .navbar-nav > .active > a:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:focus:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:focus:not(.btn) { + background-color: transparent; + border-radius: 3px; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav .nav > li > a.btn:hover, [class*="navbar-ct"] .navbar-nav .nav > li > a.btn:hover { + background-color: transparent; +} +.navbar-transparent .navbar-nav > .dropdown > a .caret, +.navbar-transparent .navbar-nav > .dropdown > a:hover .caret, +.navbar-transparent .navbar-nav > .dropdown > a:focus .caret, [class*="navbar-ct"] .navbar-nav > .dropdown > a .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:hover .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} +.navbar-transparent .navbar-nav > .open > a, +.navbar-transparent .navbar-nav > .open > a:hover, +.navbar-transparent .navbar-nav > .open > a:focus, [class*="navbar-ct"] .navbar-nav > .open > a, +[class*="navbar-ct"] .navbar-nav > .open > a:hover, +[class*="navbar-ct"] .navbar-nav > .open > a:focus { + background-color: transparent; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .btn-default, [class*="navbar-ct"] .btn-default { + color: #FFFFFF; + border-color: #FFFFFF; +} +.navbar-transparent .btn-default.btn-fill, [class*="navbar-ct"] .btn-default.btn-fill { + color: #9A9A9A; + background-color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .btn-default.btn-fill:hover, +.navbar-transparent .btn-default.btn-fill:focus, +.navbar-transparent .btn-default.btn-fill:active, +.navbar-transparent .btn-default.btn-fill.active, +.navbar-transparent .open .dropdown-toggle.btn-fill.btn-default, [class*="navbar-ct"] .btn-default.btn-fill:hover, +[class*="navbar-ct"] .btn-default.btn-fill:focus, +[class*="navbar-ct"] .btn-default.btn-fill:active, +[class*="navbar-ct"] .btn-default.btn-fill.active, +[class*="navbar-ct"] .open .dropdown-toggle.btn-fill.btn-default { + border-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} + +.navbar-transparent .dropdown-menu .divider { + background-color: rgba(255, 255, 255, 0.2); +} + +.nav-open .nav .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} + +.navbar-default { + background-color: rgba(255, 255, 255, 0.96); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); +} +.navbar-default .navbar-nav > li > a:not(.btn) { + color: #9A9A9A; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:not(.btn):hover, +.navbar-default .navbar-nav > .active > a:not(.btn):focus, +.navbar-default .navbar-nav > li > a:not(.btn):hover, +.navbar-default .navbar-nav > li > a:not(.btn):focus { + background-color: transparent; + border-radius: 3px; + color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #1DC7EA; + border-top-color: #1DC7EA; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #1DC7EA; +} +.navbar-default .navbar-nav .navbar-toggle:hover, .navbar-default .navbar-nav .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default:not(.navbar-transparent) .btn-default:hover { + color: #1DC7EA; + border-color: #1DC7EA; +} +.navbar-default:not(.navbar-transparent) .btn-neutral, .navbar-default:not(.navbar-transparent) .btn-neutral:hover, .navbar-default:not(.navbar-transparent) .btn-neutral:active { + color: #9A9A9A; +} + +/* Navbar with icons */ +.navbar-icons.navbar .navbar-brand { + margin-top: 12px; + margin-bottom: 12px; +} +.navbar-icons .navbar-nav > li > a { + text-align: center; + padding: 6px 15px; + margin: 6px 3px; +} +.navbar-icons .navbar-nav [class^="pe"] { + font-size: 30px; + position: relative; +} +.navbar-icons .navbar-nav p { + margin: 3px 0 0; +} + +.navbar-form { + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form .form-control { + border-radius: 0; + border: 0; + padding: 0; + background-color: transparent; + height: 22px; + font-size: 16px; + line-height: 1.5; + color: #E3E3E3; +} +.navbar-transparent .navbar-form .form-control, [class*="navbar-ct"] .navbar-form .form-control { + color: #FFFFFF; + border: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.6); +} + +.navbar-ct-blue { + background-color: #4091e2; +} + +.navbar-ct-azure { + background-color: #63d8f1; +} + +.navbar-ct-green { + background-color: #a1e82c; +} + +.navbar-ct-orange { + background-color: #ffbc67; +} + +.navbar-ct-red { + background-color: #fc727a; +} + +.navbar-transparent { + padding-top: 15px; + background-color: transparent; + border-bottom: 1px solid transparent; +} + +.navbar-toggle { + margin-top: 19px; + margin-bottom: 19px; + border: 0; +} +.navbar-toggle .icon-bar { + background-color: #FFFFFF; +} +.navbar-toggle .navbar-collapse, +.navbar-toggle .navbar-form { + border-color: transparent; +} +.navbar-toggle.navbar-default .navbar-toggle:hover, .navbar-toggle.navbar-default .navbar-toggle:focus { + background-color: transparent; +} + +.footer { + background-color: #FFFFFF; + line-height: 20px; +} +.footer nav > ul { + list-style: none; + margin: 0; + padding: 0; + font-weight: normal; +} +.footer nav > ul a:not(.btn) { + color: #9A9A9A; + display: block; + margin-bottom: 3px; +} +.footer nav > ul a:not(.btn):hover, .footer nav > ul a:not(.btn):focus { + color: #777777; +} +.footer .social-area { + padding: 15px 0; +} +.footer .social-area h5 { + padding-bottom: 15px; +} +.footer .social-area > a:not(.btn) { + color: #9A9A9A; + display: inline-block; + vertical-align: top; + padding: 10px 5px; + font-size: 20px; + font-weight: normal; + line-height: 20px; + text-align: center; +} +.footer .social-area > a:not(.btn):hover, .footer .social-area > a:not(.btn):focus { + color: #777777; +} +.footer .copyright { + color: #777777; + padding: 10px 15px; + margin: 10px 3px; + line-height: 20px; + font-size: 14px; +} +.footer hr { + border-color: #DDDDDD; +} +.footer .title { + color: #777777; +} + +.footer-default { + background-color: #F5F5F5; +} + +.footer:not(.footer-big) nav > ul { + font-size: 14px; +} +.footer:not(.footer-big) nav > ul li { + margin-left: 20px; + float: left; +} +.footer:not(.footer-big) nav > ul a { + padding: 10px 0px; + margin: 10px 10px 10px 0px; +} + +.dropdown-menu { + visibility: hidden; + margin: 0; + padding: 0; + border-radius: 10px; + display: block; + z-index: 9000; + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); +} +.open .dropdown-menu { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; +} +.select .dropdown-menu { + border-radius: 0 0 10px 10px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transform-origin: 50% -40px; + -moz-transform-origin: 50% -40px; + -o-transform-origin: 50% -40px; + -ms-transform-origin: 50% -40px; + transform-origin: 50% -40px; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transition: all 150ms linear; + -moz-transition: all 150ms linear; + -o-transition: all 150ms linear; + -ms-transition: all 150ms linear; + transition: all 150ms linear; + margin-top: -20px; +} +.select.open .dropdown-menu { + margin-top: -1px; +} +.dropdown-menu > li > a { + padding: 8px 16px; + color: #333333; +} +.dropdown-menu > li > a img { + margin-top: -3px; +} +.dropdown-menu > li > a:focus { + outline: 0 !important; +} +.btn-group.select .dropdown-menu { + min-width: 100%; +} +.dropdown-menu > li:first-child > a { + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} +.dropdown-menu > li:last-child > a { + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} +.select .dropdown-menu > li:first-child > a { + border-radius: 0; + border-bottom: 0 none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #F5F5F5; + color: #333333; + opacity: 1; + text-decoration: none; +} +.dropdown-menu.dropdown-blue > li > a:hover, .dropdown-menu.dropdown-blue > li > a:focus { + background-color: rgba(52, 114, 247, 0.2); +} +.dropdown-menu.dropdown-azure > li > a:hover, .dropdown-menu.dropdown-azure > li > a:focus { + background-color: rgba(29, 199, 234, 0.2); +} +.dropdown-menu.ct-green > li > a:hover, .dropdown-menu.ct-green > li > a:focus { + background-color: rgba(135, 203, 22, 0.2); +} +.dropdown-menu.dropdown-orange > li > a:hover, .dropdown-menu.dropdown-orange > li > a:focus { + background-color: rgba(255, 149, 0, 0.2); +} +.dropdown-menu.dropdown-red > li > a:hover, .dropdown-menu.dropdown-red > li > a:focus { + background-color: rgba(255, 74, 85, 0.2); +} + +.dropdown-with-icons > li > a { + padding-left: 0px; + line-height: 28px; +} +.dropdown-with-icons i { + text-align: center; + line-height: 28px; + float: left; +} +.dropdown-with-icons i[class^="pe-"] { + font-size: 24px; + width: 46px; +} +.dropdown-with-icons i[class^="fa"] { + font-size: 14px; + width: 38px; +} + +.btn-group.select { + overflow: hidden; +} + +.btn-group.select.open { + overflow: visible; +} + +.card { + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(63, 63, 68, 0.1); + background-color: #FFFFFF; + margin-bottom: 30px; +} +.card .image { + width: 100%; + overflow: hidden; + height: 260px; + border-radius: 4px 4px 0 0; + position: relative; + -webkit-transform-style: preserve-3d; + -moz-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.card .image img { + width: 100%; +} +.card .filter { + position: absolute; + z-index: 2; + background-color: rgba(0, 0, 0, 0.68); + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + filter: alpha(opacity=0); +} +.card .filter .btn { + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} +.card:hover .filter { + opacity: 1; + filter: alpha(opacity=100); +} +.card .btn-hover { + opacity: 0; + filter: alpha(opacity=0); +} +.card:hover .btn-hover { + opacity: 1; + filter: alpha(opacity=100); +} +.card .content { + padding: 15px 15px 10px 15px; +} +.card .header { + padding: 15px 15px 0; +} +.card .category, +.card label { + font-size: 14px; + font-weight: 400; + color: #9A9A9A; + margin-bottom: 0px; +} +.card .category i, +.card label i { + font-size: 16px; +} +.card label { + font-size: 12px; + margin-bottom: 5px; + text-transform: uppercase; +} +.card .title { + margin: 0; + color: #333333; + font-weight: 300; +} +.card .avatar { + width: 30px; + height: 30px; + overflow: hidden; + border-radius: 50%; + margin-right: 5px; +} +.card .description { + font-size: 14px; + color: #333; +} +.card .footer { + padding: 0; + background-color: transparent; + line-height: 30px; +} +.card .footer .legend { + padding: 5px 0; +} +.card .footer hr { + margin-top: 5px; + margin-bottom: 5px; +} +.card .stats { + color: #a9a9a9; +} +.card .footer div { + display: inline-block; +} +.card .author { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.card .author i { + font-size: 14px; +} +.card h6 { + font-size: 12px; + margin: 0; +} +.card.card-separator:after { + height: 100%; + right: -15px; + top: 0; + width: 1px; + background-color: #DDDDDD; + content: ""; + position: absolute; +} +.card .ct-chart { + margin: 30px 0 30px; + height: 245px; +} +.card .table tbody td:first-child, +.card .table thead th:first-child { + padding-left: 15px; +} +.card .table tbody td:last-child, +.card .table thead th:last-child { + padding-right: 15px; +} +.card .alert { + border-radius: 4px; + position: relative; +} +.card .alert.alert-with-icon { + padding-left: 65px; +} + +.card-user .image { + height: 110px; +} +.card-user .image-plain { + height: 0; + margin-top: 110px; +} +.card-user .author { + text-align: center; + text-transform: none; + margin-top: -70px; +} +.card-user .avatar { + width: 124px; + height: 124px; + border: 5px solid #FFFFFF; + position: relative; + margin-bottom: 15px; +} +.card-user .avatar.border-gray { + border-color: #EEEEEE; +} +.card-user .title { + line-height: 24px; +} +.card-user .content { + min-height: 240px; +} + +.card-user .footer, +.card-price .footer { + padding: 5px 15px 10px; +} +.card-user hr, +.card-price hr { + margin: 5px 15px; +} + +.card-plain { + background-color: transparent; + box-shadow: none; + border-radius: 0; +} +.card-plain .image { + border-radius: 4px; +} + +.ct-label { + fill: rgba(0, 0, 0, 0.4); + color: rgba(0, 0, 0, 0.4); + font-size: 1.3rem; + line-height: 1; +} + +.ct-chart-line .ct-label, +.ct-chart-bar .ct-label { + display: block; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-vertical.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-label.ct-vertical.ct-end { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: end; +} + +.ct-grid { + stroke: rgba(0, 0, 0, 0.2); + stroke-width: 1px; + stroke-dasharray: 2px; +} + +.ct-point { + stroke-width: 8px; + stroke-linecap: round; +} + +.ct-line { + fill: none; + stroke-width: 3px; +} + +.ct-area { + stroke: none; + fill-opacity: 0.8; +} + +.ct-bar { + fill: none; + stroke-width: 10px; +} + +.ct-slice-donut { + fill: none; + stroke-width: 60px; +} + +.ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut { + stroke: #1DC7EA; +} +.ct-series-a .ct-slice-pie, .ct-series-a .ct-area { + fill: #1DC7EA; +} + +.ct-series-b .ct-point, .ct-series-b .ct-line, .ct-series-b .ct-bar, .ct-series-b .ct-slice-donut { + stroke: #FB404B; +} +.ct-series-b .ct-slice-pie, .ct-series-b .ct-area { + fill: #FB404B; +} + +.ct-series-c .ct-point, .ct-series-c .ct-line, .ct-series-c .ct-bar, .ct-series-c .ct-slice-donut { + stroke: #FFA534; +} +.ct-series-c .ct-slice-pie, .ct-series-c .ct-area { + fill: #FFA534; +} + +.ct-series-d .ct-point, .ct-series-d .ct-line, .ct-series-d .ct-bar, .ct-series-d .ct-slice-donut { + stroke: #9368E9; +} +.ct-series-d .ct-slice-pie, .ct-series-d .ct-area { + fill: #9368E9; +} + +.ct-series-e .ct-point, .ct-series-e .ct-line, .ct-series-e .ct-bar, .ct-series-e .ct-slice-donut { + stroke: #87CB16; +} +.ct-series-e .ct-slice-pie, .ct-series-e .ct-area { + fill: #87CB16; +} + +.ct-series-f .ct-point, .ct-series-f .ct-line, .ct-series-f .ct-bar, .ct-series-f .ct-slice-donut { + stroke: #1F77D0; +} +.ct-series-f .ct-slice-pie, .ct-series-f .ct-area { + fill: #1F77D0; +} + +.ct-series-g .ct-point, .ct-series-g .ct-line, .ct-series-g .ct-bar, .ct-series-g .ct-slice-donut { + stroke: #5e5e5e; +} +.ct-series-g .ct-slice-pie, .ct-series-g .ct-area { + fill: #5e5e5e; +} + +.ct-series-h .ct-point, .ct-series-h .ct-line, .ct-series-h .ct-bar, .ct-series-h .ct-slice-donut { + stroke: #dd4b39; +} +.ct-series-h .ct-slice-pie, .ct-series-h .ct-area { + fill: #dd4b39; +} + +.ct-series-i .ct-point, .ct-series-i .ct-line, .ct-series-i .ct-bar, .ct-series-i .ct-slice-donut { + stroke: #35465c; +} +.ct-series-i .ct-slice-pie, .ct-series-i .ct-area { + fill: #35465c; +} + +.ct-series-j .ct-point, .ct-series-j .ct-line, .ct-series-j .ct-bar, .ct-series-j .ct-slice-donut { + stroke: #e52d27; +} +.ct-series-j .ct-slice-pie, .ct-series-j .ct-area { + fill: #e52d27; +} + +.ct-series-k .ct-point, .ct-series-k .ct-line, .ct-series-k .ct-bar, .ct-series-k .ct-slice-donut { + stroke: #55acee; +} +.ct-series-k .ct-slice-pie, .ct-series-k .ct-area { + fill: #55acee; +} + +.ct-series-l .ct-point, .ct-series-l .ct-line, .ct-series-l .ct-bar, .ct-series-l .ct-slice-donut { + stroke: #cc2127; +} +.ct-series-l .ct-slice-pie, .ct-series-l .ct-area { + fill: #cc2127; +} + +.ct-series-m .ct-point, .ct-series-m .ct-line, .ct-series-m .ct-bar, .ct-series-m .ct-slice-donut { + stroke: #1769ff; +} +.ct-series-m .ct-slice-pie, .ct-series-m .ct-area { + fill: #1769ff; +} + +.ct-series-n .ct-point, .ct-series-n .ct-line, .ct-series-n .ct-bar, .ct-series-n .ct-slice-donut { + stroke: #6188e2; +} +.ct-series-n .ct-slice-pie, .ct-series-n .ct-area { + fill: #6188e2; +} + +.ct-series-o .ct-point, .ct-series-o .ct-line, .ct-series-o .ct-bar, .ct-series-o .ct-slice-donut { + stroke: #a748ca; +} +.ct-series-o .ct-slice-pie, .ct-series-o .ct-area { + fill: #a748ca; +} + +.ct-square { + display: block; + position: relative; + width: 100%; +} +.ct-square:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 100%; +} +.ct-square:after { + content: ""; + display: table; + clear: both; +} +.ct-square > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-second { + display: block; + position: relative; + width: 100%; +} +.ct-minor-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 93.75%; +} +.ct-minor-second:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-second { + display: block; + position: relative; + width: 100%; +} +.ct-major-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 88.88889%; +} +.ct-major-second:after { + content: ""; + display: table; + clear: both; +} +.ct-major-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-third { + display: block; + position: relative; + width: 100%; +} +.ct-minor-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 83.33333%; +} +.ct-minor-third:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-third { + display: block; + position: relative; + width: 100%; +} +.ct-major-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 80%; +} +.ct-major-third:after { + content: ""; + display: table; + clear: both; +} +.ct-major-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fourth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fourth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 75%; +} +.ct-perfect-fourth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fourth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fifth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fifth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 66.66667%; +} +.ct-perfect-fifth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fifth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-minor-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 62.5%; +} +.ct-minor-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-golden-section { + display: block; + position: relative; + width: 100%; +} +.ct-golden-section:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 61.8047%; +} +.ct-golden-section:after { + content: ""; + display: table; + clear: both; +} +.ct-golden-section > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-major-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 60%; +} +.ct-major-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-minor-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 56.25%; +} +.ct-minor-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 53.33333%; +} +.ct-major-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-octave { + display: block; + position: relative; + width: 100%; +} +.ct-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 50%; +} +.ct-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-tenth { + display: block; + position: relative; + width: 100%; +} +.ct-major-tenth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 40%; +} +.ct-major-tenth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-tenth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-eleventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-eleventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 37.5%; +} +.ct-major-eleventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-eleventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-twelfth { + display: block; + position: relative; + width: 100%; +} +.ct-major-twelfth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 33.33333%; +} +.ct-major-twelfth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-twelfth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-double-octave { + display: block; + position: relative; + width: 100%; +} +.ct-double-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 25%; +} +.ct-double-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-double-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +@media (min-width: 992px) { + .navbar-form { + margin-top: 21px; + margin-bottom: 21px; + padding-left: 5px; + padding-right: 5px; + } + + .navbar-nav > li > .dropdown-menu, .dropdown .dropdown-menu { + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -moz-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -o-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -ms-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + } + + .navbar-nav > li.open > .dropdown-menu, .dropdown.open .dropdown-menu { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transform-origin: 29px -50px; + -moz-transform-origin: 29px -50px; + -o-transform-origin: 29px -50px; + -ms-transform-origin: 29px -50px; + transform-origin: 29px -50px; + } + + .navbar-nav > li > .dropdown-menu:before { + border-bottom: 11px solid rgba(0, 0, 0, 0.2); + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -11px; + } + + .navbar-nav > li > .dropdown-menu:after { + border-bottom: 11px solid #FFFFFF; + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -10px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:before { + left: auto; + right: 12px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:after { + left: auto; + right: 12px; + } + + .footer:not(.footer-big) nav > ul li:first-child { + margin-left: 0; + } + + body > .navbar-collapse.collapse { + display: none !important; + } + + .card form [class*="col-"] { + padding: 6px; + } + .card form [class*="col-"]:first-child { + padding-left: 15px; + } + .card form [class*="col-"]:last-child { + padding-right: 15px; + } +} +/* Changes for small display */ +@media (max-width: 991px) { + .sidebar { + display: none; + } + + .main-panel { + width: 100%; + } + + .navbar-transparent { + padding-top: 15px; + background-color: rgba(0, 0, 0, 0.45); + } + + body { + position: relative; + } + + .wrapper { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + left: 0; + background-color: white; + } + + .navbar .container { + left: 0; + width: 100%; + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + position: relative; + } + + .navbar .navbar-collapse.collapse, + .navbar .navbar-collapse.collapse.in, + .navbar .navbar-collapse.collapsing { + display: none !important; + } + + .navbar-nav > li { + float: none; + position: relative; + display: block; + } + + body > .navbar-collapse { + position: fixed; + display: block; + top: 0; + height: 100%; + width: 250px; + right: 0; + z-index: 1032; + visibility: visible; + background-color: #999; + overflow-y: visible; + border-top: none; + text-align: left; + padding: 0; + -webkit-transform: translate3d(250px, 0, 0); + -moz-transform: translate3d(250px, 0, 0); + -o-transform: translate3d(250px, 0, 0); + -ms-transform: translate3d(250px, 0, 0); + transform: translate3d(250px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + } + body > .navbar-collapse > ul { + position: relative; + z-index: 4; + overflow-y: scroll; + height: calc(100vh - 61px); + width: 100%; + } + body > .navbar-collapse .nav > li > a { + padding: 30px 25px; + } + body > .navbar-collapse::before { + top: 0; + left: 0; + height: 100%; + width: 100%; + position: absolute; + background-color: #282828; + display: block; + content: ""; + z-index: 1; + } + body > .navbar-collapse .logo { + position: relative; + z-index: 4; + } + + .nav-open .navbar-collapse { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + } + + .nav-open .navbar .container { + left: -250px; + } + + .nav-open .wrapper { + left: 0; + -webkit-transform: translate3d(-250px, 0, 0); + -moz-transform: translate3d(-250px, 0, 0); + -o-transform: translate3d(-250px, 0, 0); + -ms-transform: translate3d(-250px, 0, 0); + transform: translate3d(-250px, 0, 0); + } + + .navbar-toggle .icon-bar { + display: block; + position: relative; + background: #fff; + width: 24px; + height: 2px; + border-radius: 1px; + margin: 0 auto; + } + + .navbar-header .navbar-toggle { + margin: 10px 15px 10px 0; + width: 40px; + height: 40px; + } + + .bar1, + .bar2, + .bar3 { + outline: 1px solid transparent; + } + + .bar1 { + top: 0px; + -webkit-animation: topbar-back 500ms linear 0s; + -moz-animation: topbar-back 500ms linear 0s; + animation: topbar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .bar2 { + opacity: 1; + } + + .bar3 { + bottom: 0px; + -webkit-animation: bottombar-back 500ms linear 0s; + -moz-animation: bottombar-back 500ms linear 0s; + animation: bottombar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar1 { + top: 6px; + -webkit-animation: topbar-x 500ms linear 0s; + -moz-animation: topbar-x 500ms linear 0s; + animation: topbar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar2 { + opacity: 0; + } + + .toggled .bar3 { + bottom: 6px; + -webkit-animation: bottombar-x 500ms linear 0s; + -moz-animation: bottombar-x 500ms linear 0s; + animation: bottombar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + @keyframes topbar-x { + 0% { + top: 0px; + transform: rotate(0deg); + } + 45% { + top: 6px; + transform: rotate(145deg); + } + 75% { + transform: rotate(130deg); + } + 100% { + transform: rotate(135deg); + } + } + @-webkit-keyframes topbar-x { + 0% { + top: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + top: 6px; + -webkit-transform: rotate(145deg); + } + 75% { + -webkit-transform: rotate(130deg); + } + 100% { + -webkit-transform: rotate(135deg); + } + } + @-moz-keyframes topbar-x { + 0% { + top: 0px; + -moz-transform: rotate(0deg); + } + 45% { + top: 6px; + -moz-transform: rotate(145deg); + } + 75% { + -moz-transform: rotate(130deg); + } + 100% { + -moz-transform: rotate(135deg); + } + } + @keyframes topbar-back { + 0% { + top: 6px; + transform: rotate(135deg); + } + 45% { + transform: rotate(-10deg); + } + 75% { + transform: rotate(5deg); + } + 100% { + top: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes topbar-back { + 0% { + top: 6px; + -webkit-transform: rotate(135deg); + } + 45% { + -webkit-transform: rotate(-10deg); + } + 75% { + -webkit-transform: rotate(5deg); + } + 100% { + top: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes topbar-back { + 0% { + top: 6px; + -moz-transform: rotate(135deg); + } + 45% { + -moz-transform: rotate(-10deg); + } + 75% { + -moz-transform: rotate(5deg); + } + 100% { + top: 0px; + -moz-transform: rotate(0); + } + } + @keyframes bottombar-x { + 0% { + bottom: 0px; + transform: rotate(0deg); + } + 45% { + bottom: 6px; + transform: rotate(-145deg); + } + 75% { + transform: rotate(-130deg); + } + 100% { + transform: rotate(-135deg); + } + } + @-webkit-keyframes bottombar-x { + 0% { + bottom: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -webkit-transform: rotate(-145deg); + } + 75% { + -webkit-transform: rotate(-130deg); + } + 100% { + -webkit-transform: rotate(-135deg); + } + } + @-moz-keyframes bottombar-x { + 0% { + bottom: 0px; + -moz-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -moz-transform: rotate(-145deg); + } + 75% { + -moz-transform: rotate(-130deg); + } + 100% { + -moz-transform: rotate(-135deg); + } + } + @keyframes bottombar-back { + 0% { + bottom: 6px; + transform: rotate(-135deg); + } + 45% { + transform: rotate(10deg); + } + 75% { + transform: rotate(-5deg); + } + 100% { + bottom: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes bottombar-back { + 0% { + bottom: 6px; + -webkit-transform: rotate(-135deg); + } + 45% { + -webkit-transform: rotate(10deg); + } + 75% { + -webkit-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes bottombar-back { + 0% { + bottom: 6px; + -moz-transform: rotate(-135deg); + } + 45% { + -moz-transform: rotate(10deg); + } + 75% { + -moz-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -moz-transform: rotate(0); + } + } + @-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @-moz-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + .dropdown-menu .divider { + background-color: rgba(229, 229, 229, 0.15); + } + + .navbar-nav { + margin: 1px 0; + } + .navbar-nav .open .dropdown-menu > li > a { + padding: 15px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:first-child > a { + padding: 5px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:last-child > a { + padding: 15px 15px 25px 50px; + } + + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .active > a, + [class*="navbar-"] .navbar-nav .active > a:hover, + [class*="navbar-"] .navbar-nav .active > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus, + [class*="navbar-"] .navbar-nav .navbar-nav .open .dropdown-menu > li > a:active { + color: white; + } + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus { + opacity: .7; + background: transparent; + } + [class*="navbar-"] .navbar-nav.navbar-nav .open .dropdown-menu > li > a:active { + opacity: 1; + } + [class*="navbar-"] .navbar-nav .dropdown > a:hover .caret { + border-bottom-color: #777; + border-top-color: #777; + } + [class*="navbar-"] .navbar-nav .dropdown > a:active .caret { + border-bottom-color: white; + border-top-color: white; + } + + .dropdown-menu { + display: none; + } + + .navbar-fixed-top { + -webkit-backface-visibility: hidden; + } + + #bodyClick { + height: 100%; + width: 100%; + position: fixed; + opacity: 0; + top: 0; + left: auto; + right: 250px; + content: ""; + z-index: 9999; + overflow-x: hidden; + } + + .social-line .btn { + margin: 0 0 10px 0; + } + + .subscribe-line .form-control { + margin: 0 0 10px 0; + } + + .social-line.pull-right { + float: none; + } + + .footer nav.pull-left { + float: none !important; + } + + .footer:not(.footer-big) nav > ul li { + float: none; + } + + .social-area.pull-right { + float: none !important; + } + + .form-control + .form-control-feedback { + margin-top: -8px; + } + + .navbar-toggle:hover, .navbar-toggle:focus { + background-color: transparent !important; + } + + .btn.dropdown-toggle { + margin-bottom: 0; + } + + .media-post .author { + width: 20%; + float: none !important; + display: block; + margin: 0 auto 10px; + } + + .media-post .media-body { + width: 100%; + } + + .navbar-collapse.collapse { + height: 100% !important; + } + + .navbar-collapse.collapse.in { + display: block; + } + + .navbar-header .collapse, .navbar-toggle { + display: block !important; + } + + .navbar-header { + float: none; + } + + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + + .navbar-collapse .nav p { + font-size: 14px; + margin: 0; + } + .navbar-collapse [class^="pe-7s-"] { + float: left; + font-size: 20px; + margin-right: 10px; + } +} +@media (min-width: 992px) { + .table-full-width { + margin-left: -15px; + margin-right: -15px; + } + + .table-responsive { + overflow: visible; + } +} +@media (max-width: 991px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; + } +} diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/pe-icon-7-stroke.css b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/pe-icon-7-stroke.css new file mode 100644 index 0000000..44bcbaa --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/css/pe-icon-7-stroke.css @@ -0,0 +1,632 @@ +@font-face { + font-family: 'Pe-icon-7-stroke'; + src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v'); + src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'), + url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'), + url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'), + url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="pe-7s-"], [class*=" pe-7s-"] { + display: inline-block; + font-family: 'Pe-icon-7-stroke'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.pe-7s-album:before { + content: "\e6aa"; +} +.pe-7s-arc:before { + content: "\e6ab"; +} +.pe-7s-back-2:before { + content: "\e6ac"; +} +.pe-7s-bandaid:before { + content: "\e6ad"; +} +.pe-7s-car:before { + content: "\e6ae"; +} +.pe-7s-diamond:before { + content: "\e6af"; +} +.pe-7s-door-lock:before { + content: "\e6b0"; +} +.pe-7s-eyedropper:before { + content: "\e6b1"; +} +.pe-7s-female:before { + content: "\e6b2"; +} +.pe-7s-gym:before { + content: "\e6b3"; +} +.pe-7s-hammer:before { + content: "\e6b4"; +} +.pe-7s-headphones:before { + content: "\e6b5"; +} +.pe-7s-helm:before { + content: "\e6b6"; +} +.pe-7s-hourglass:before { + content: "\e6b7"; +} +.pe-7s-leaf:before { + content: "\e6b8"; +} +.pe-7s-magic-wand:before { + content: "\e6b9"; +} +.pe-7s-male:before { + content: "\e6ba"; +} +.pe-7s-map-2:before { + content: "\e6bb"; +} +.pe-7s-next-2:before { + content: "\e6bc"; +} +.pe-7s-paint-bucket:before { + content: "\e6bd"; +} +.pe-7s-pendrive:before { + content: "\e6be"; +} +.pe-7s-photo:before { + content: "\e6bf"; +} +.pe-7s-piggy:before { + content: "\e6c0"; +} +.pe-7s-plugin:before { + content: "\e6c1"; +} +.pe-7s-refresh-2:before { + content: "\e6c2"; +} +.pe-7s-rocket:before { + content: "\e6c3"; +} +.pe-7s-settings:before { + content: "\e6c4"; +} +.pe-7s-shield:before { + content: "\e6c5"; +} +.pe-7s-smile:before { + content: "\e6c6"; +} +.pe-7s-usb:before { + content: "\e6c7"; +} +.pe-7s-vector:before { + content: "\e6c8"; +} +.pe-7s-wine:before { + content: "\e6c9"; +} +.pe-7s-cloud-upload:before { + content: "\e68a"; +} +.pe-7s-cash:before { + content: "\e68c"; +} +.pe-7s-close:before { + content: "\e680"; +} +.pe-7s-bluetooth:before { + content: "\e68d"; +} +.pe-7s-cloud-download:before { + content: "\e68b"; +} +.pe-7s-way:before { + content: "\e68e"; +} +.pe-7s-close-circle:before { + content: "\e681"; +} +.pe-7s-id:before { + content: "\e68f"; +} +.pe-7s-angle-up:before { + content: "\e682"; +} +.pe-7s-wristwatch:before { + content: "\e690"; +} +.pe-7s-angle-up-circle:before { + content: "\e683"; +} +.pe-7s-world:before { + content: "\e691"; +} +.pe-7s-angle-right:before { + content: "\e684"; +} +.pe-7s-volume:before { + content: "\e692"; +} +.pe-7s-angle-right-circle:before { + content: "\e685"; +} +.pe-7s-users:before { + content: "\e693"; +} +.pe-7s-angle-left:before { + content: "\e686"; +} +.pe-7s-user-female:before { + content: "\e694"; +} +.pe-7s-angle-left-circle:before { + content: "\e687"; +} +.pe-7s-up-arrow:before { + content: "\e695"; +} +.pe-7s-angle-down:before { + content: "\e688"; +} +.pe-7s-switch:before { + content: "\e696"; +} +.pe-7s-angle-down-circle:before { + content: "\e689"; +} +.pe-7s-scissors:before { + content: "\e697"; +} +.pe-7s-wallet:before { + content: "\e600"; +} +.pe-7s-safe:before { + content: "\e698"; +} +.pe-7s-volume2:before { + content: "\e601"; +} +.pe-7s-volume1:before { + content: "\e602"; +} +.pe-7s-voicemail:before { + content: "\e603"; +} +.pe-7s-video:before { + content: "\e604"; +} +.pe-7s-user:before { + content: "\e605"; +} +.pe-7s-upload:before { + content: "\e606"; +} +.pe-7s-unlock:before { + content: "\e607"; +} +.pe-7s-umbrella:before { + content: "\e608"; +} +.pe-7s-trash:before { + content: "\e609"; +} +.pe-7s-tools:before { + content: "\e60a"; +} +.pe-7s-timer:before { + content: "\e60b"; +} +.pe-7s-ticket:before { + content: "\e60c"; +} +.pe-7s-target:before { + content: "\e60d"; +} +.pe-7s-sun:before { + content: "\e60e"; +} +.pe-7s-study:before { + content: "\e60f"; +} +.pe-7s-stopwatch:before { + content: "\e610"; +} +.pe-7s-star:before { + content: "\e611"; +} +.pe-7s-speaker:before { + content: "\e612"; +} +.pe-7s-signal:before { + content: "\e613"; +} +.pe-7s-shuffle:before { + content: "\e614"; +} +.pe-7s-shopbag:before { + content: "\e615"; +} +.pe-7s-share:before { + content: "\e616"; +} +.pe-7s-server:before { + content: "\e617"; +} +.pe-7s-search:before { + content: "\e618"; +} +.pe-7s-film:before { + content: "\e6a5"; +} +.pe-7s-science:before { + content: "\e619"; +} +.pe-7s-disk:before { + content: "\e6a6"; +} +.pe-7s-ribbon:before { + content: "\e61a"; +} +.pe-7s-repeat:before { + content: "\e61b"; +} +.pe-7s-refresh:before { + content: "\e61c"; +} +.pe-7s-add-user:before { + content: "\e6a9"; +} +.pe-7s-refresh-cloud:before { + content: "\e61d"; +} +.pe-7s-paperclip:before { + content: "\e69c"; +} +.pe-7s-radio:before { + content: "\e61e"; +} +.pe-7s-note2:before { + content: "\e69d"; +} +.pe-7s-print:before { + content: "\e61f"; +} +.pe-7s-network:before { + content: "\e69e"; +} +.pe-7s-prev:before { + content: "\e620"; +} +.pe-7s-mute:before { + content: "\e69f"; +} +.pe-7s-power:before { + content: "\e621"; +} +.pe-7s-medal:before { + content: "\e6a0"; +} +.pe-7s-portfolio:before { + content: "\e622"; +} +.pe-7s-like2:before { + content: "\e6a1"; +} +.pe-7s-plus:before { + content: "\e623"; +} +.pe-7s-left-arrow:before { + content: "\e6a2"; +} +.pe-7s-play:before { + content: "\e624"; +} +.pe-7s-key:before { + content: "\e6a3"; +} +.pe-7s-plane:before { + content: "\e625"; +} +.pe-7s-joy:before { + content: "\e6a4"; +} +.pe-7s-photo-gallery:before { + content: "\e626"; +} +.pe-7s-pin:before { + content: "\e69b"; +} +.pe-7s-phone:before { + content: "\e627"; +} +.pe-7s-plug:before { + content: "\e69a"; +} +.pe-7s-pen:before { + content: "\e628"; +} +.pe-7s-right-arrow:before { + content: "\e699"; +} +.pe-7s-paper-plane:before { + content: "\e629"; +} +.pe-7s-delete-user:before { + content: "\e6a7"; +} +.pe-7s-paint:before { + content: "\e62a"; +} +.pe-7s-bottom-arrow:before { + content: "\e6a8"; +} +.pe-7s-notebook:before { + content: "\e62b"; +} +.pe-7s-note:before { + content: "\e62c"; +} +.pe-7s-next:before { + content: "\e62d"; +} +.pe-7s-news-paper:before { + content: "\e62e"; +} +.pe-7s-musiclist:before { + content: "\e62f"; +} +.pe-7s-music:before { + content: "\e630"; +} +.pe-7s-mouse:before { + content: "\e631"; +} +.pe-7s-more:before { + content: "\e632"; +} +.pe-7s-moon:before { + content: "\e633"; +} +.pe-7s-monitor:before { + content: "\e634"; +} +.pe-7s-micro:before { + content: "\e635"; +} +.pe-7s-menu:before { + content: "\e636"; +} +.pe-7s-map:before { + content: "\e637"; +} +.pe-7s-map-marker:before { + content: "\e638"; +} +.pe-7s-mail:before { + content: "\e639"; +} +.pe-7s-mail-open:before { + content: "\e63a"; +} +.pe-7s-mail-open-file:before { + content: "\e63b"; +} +.pe-7s-magnet:before { + content: "\e63c"; +} +.pe-7s-loop:before { + content: "\e63d"; +} +.pe-7s-look:before { + content: "\e63e"; +} +.pe-7s-lock:before { + content: "\e63f"; +} +.pe-7s-lintern:before { + content: "\e640"; +} +.pe-7s-link:before { + content: "\e641"; +} +.pe-7s-like:before { + content: "\e642"; +} +.pe-7s-light:before { + content: "\e643"; +} +.pe-7s-less:before { + content: "\e644"; +} +.pe-7s-keypad:before { + content: "\e645"; +} +.pe-7s-junk:before { + content: "\e646"; +} +.pe-7s-info:before { + content: "\e647"; +} +.pe-7s-home:before { + content: "\e648"; +} +.pe-7s-help2:before { + content: "\e649"; +} +.pe-7s-help1:before { + content: "\e64a"; +} +.pe-7s-graph3:before { + content: "\e64b"; +} +.pe-7s-graph2:before { + content: "\e64c"; +} +.pe-7s-graph1:before { + content: "\e64d"; +} +.pe-7s-graph:before { + content: "\e64e"; +} +.pe-7s-global:before { + content: "\e64f"; +} +.pe-7s-gleam:before { + content: "\e650"; +} +.pe-7s-glasses:before { + content: "\e651"; +} +.pe-7s-gift:before { + content: "\e652"; +} +.pe-7s-folder:before { + content: "\e653"; +} +.pe-7s-flag:before { + content: "\e654"; +} +.pe-7s-filter:before { + content: "\e655"; +} +.pe-7s-file:before { + content: "\e656"; +} +.pe-7s-expand1:before { + content: "\e657"; +} +.pe-7s-exapnd2:before { + content: "\e658"; +} +.pe-7s-edit:before { + content: "\e659"; +} +.pe-7s-drop:before { + content: "\e65a"; +} +.pe-7s-drawer:before { + content: "\e65b"; +} +.pe-7s-download:before { + content: "\e65c"; +} +.pe-7s-display2:before { + content: "\e65d"; +} +.pe-7s-display1:before { + content: "\e65e"; +} +.pe-7s-diskette:before { + content: "\e65f"; +} +.pe-7s-date:before { + content: "\e660"; +} +.pe-7s-cup:before { + content: "\e661"; +} +.pe-7s-culture:before { + content: "\e662"; +} +.pe-7s-crop:before { + content: "\e663"; +} +.pe-7s-credit:before { + content: "\e664"; +} +.pe-7s-copy-file:before { + content: "\e665"; +} +.pe-7s-config:before { + content: "\e666"; +} +.pe-7s-compass:before { + content: "\e667"; +} +.pe-7s-comment:before { + content: "\e668"; +} +.pe-7s-coffee:before { + content: "\e669"; +} +.pe-7s-cloud:before { + content: "\e66a"; +} +.pe-7s-clock:before { + content: "\e66b"; +} +.pe-7s-check:before { + content: "\e66c"; +} +.pe-7s-chat:before { + content: "\e66d"; +} +.pe-7s-cart:before { + content: "\e66e"; +} +.pe-7s-camera:before { + content: "\e66f"; +} +.pe-7s-call:before { + content: "\e670"; +} +.pe-7s-calculator:before { + content: "\e671"; +} +.pe-7s-browser:before { + content: "\e672"; +} +.pe-7s-box2:before { + content: "\e673"; +} +.pe-7s-box1:before { + content: "\e674"; +} +.pe-7s-bookmarks:before { + content: "\e675"; +} +.pe-7s-bicycle:before { + content: "\e676"; +} +.pe-7s-bell:before { + content: "\e677"; +} +.pe-7s-battery:before { + content: "\e678"; +} +.pe-7s-ball:before { + content: "\e679"; +} +.pe-7s-back:before { + content: "\e67a"; +} +.pe-7s-attention:before { + content: "\e67b"; +} +.pe-7s-anchor:before { + content: "\e67c"; +} +.pe-7s-albums:before { + content: "\e67d"; +} +.pe-7s-alarm:before { + content: "\e67e"; +} +.pe-7s-airplay:before { + content: "\e67f"; +} diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot new file mode 100644 index 0000000000000000000000000000000000000000..6f7b58489c6fe76af1597fad93bd8ebe36114eb9 GIT binary patch literal 58680 zcmd4437i~9eJ|cMGu=IX%}md|bL{TS?CwarEA25m8d#{XY4B-W!c}s=KSJyQ`~y$M<*C;vY%U&L2t=lLFGr50gH`XwRn0XYQxE;`7vJ z?p`tbm?X7JmrL8F1=8E3TcmO6E|ePhf46jx^mc6Dj$@J(k*>t=4(VR$4(TTBm!z~b zial>fy|?kR+NA+$q12BfZ=^j`qnk3MNhv7xZ@H>(FkF7^J=k*;|8KnI&YO1TMozS& zQUTkWcHDILPW;BOeH(tmJMMVL*jJ9MKwXCY-}$%Ow%>GXV6FD7B)xnqjxV|mJAyw9 zJcaGw$9BhUciuDcE+hYLY=2pjf{X7MzvZUPuN!^>HEKj z`t5h!bm#W_P8`Ph-~S?xe{ARY-S^-=@%iE9bX*DsB=#Xm#<5Lo413nQzyB_^NDopy z--qG0XMR>m(wP_8>2vtUPNOw6;!vC%1ga?(U)SV zNUTyH>Z&eel~P$zBP?Yn)3wszqPjiQRp~4ZrZcUq$V&C0MU54##!7a{t|n<`ZIJf3 z=ZaHnNot`|rsmue`1vXJ<;99DN5aml;fSm#VVOtOLilTa@VN}p%Sr3Nr5v5>=UERmqQxt0Z05!>aWOXfXtgla2gTWA5EIX(6 zg<}f;#KKxkM#Hia(_}4#=7J$jRy5JBrr`bbNCrE}o{l-reMmj;*)xrWjE2>Dz165j7!4C&ul#XDi^}{H)gn4xkc@9kpRbxBIfSpNMpQ$* zB14VLmubx46P7WWf`K5u7y;LMotNy2$J;D3Qcfhg(_TNPyAz3W#I)Mt@vfx5gKyN$ zd^Fk~i?v6ic~iGqW3h5PUXI0Dtm{n{$Bn4n_5`RAd0-kT9`y~2Js+Z~I>!>XFJ4q8c74acLg?rgR@8jHtc z(e5nEd1dFpm}PY&Q%@T3SJtZCy=UW=;>VP%xmdU^ozD z0mcFWMGxt!8aHh-uBv*_kg<>969}q7rUYoi$XRAuF^F)tw&aGZ?^RQne7X@tTOqU( zKs9O#ZHGgeB3o)KY$;$78t4Hv2C9HsGAOe8vNyJ)eeX5BNtdz)X% zE=8jS6Z8e#i3L@~l;wCh6tzs;XE1B3#YhO8NMTF?FA7D9s+kQk*)XkWC>$qp6%MeV z76P3z3$Z9TCUuANd{7M$yNiXDSXhpQ8T!IBHM&VAw;G|e5kmh283REJhm3T{XhpZ+ zIW^Nndn^pX7}eBRh}uzue9B_>CM+6n0cqsiPuOAh03?f~By~2bYNlb=Y_(ni%dVtq z_{%n$S6^*j93L8IL*tXqp{Mz#^Gg^wY6K*&+gBl@sMM zKgMf~{rJb8_h{Ch+zfOon|{t7|1JP zYWb_DYE7Y~n&DJd%oIUb=PdL2AzI4_w#Kx0?YeTQ%9yR;9q0xpphQd!Jprud96?XM{~TgcB0l?6MW&`*q?hh8&#N-oCZ3Z)L6$LEzGT4~C{D_UF2<<{0K7J_yLLy$SPL1sD#nW;nSlU7J;r1juq(~@P6 zU}rQ^Y6(t6mNN0S6194DXc4wRmn-!|Y9Ohga#wwz9;^j}HM?RPOid)J!3;Y%qJ(5q z9aYg!%1GP>#kJJuR0~wswomCepidmuu}8Ph*%R@2DQ?H7Y};lJ*t`<2Z`;mMZ;K7v zwyNtY_I{jEfw48tU$ByMmf7^5HUH533Q5Itzh*yTFF<+PBfTJ<#Js3tl2sc`QJ5&` zqOLv`Wh+VW!PgyB7{f|BgPJrYGZKLAbPGgDk*jU2YRDjokekJR6U1D;WXxRCvBn(Rfbj`QC>&9B><`NFyw<9Ly3^G) z6J#y4VR?sXUdIU`$Rm+463d5jCWRTG*l-D7miiJz*6Z!Bc@| z9Xy8$y5GVUw}3&rvfZRDuNceuH!n=7lyCH6D{9>+XA^(^sHs(Eu)LI z&I2_EpAdV~rrBa`aG&N9sv6Q%Eo)h*JFl%O<6#+b9_&n;R*QLwcoG>`$5#%5G(*W? zSJIO>KQK~621rm1u$IL+Ev|)ag>Qm6J*DVr-Jrvq+~*dt7A*nAL`4Pc2?m~$x6^&o z?Q5j;aGKnd>vPgpXny_af#$%YQPJO3sdkm|V)5R)G0`y9>U`|D!k$kEbmecs&Syv> zKVui&uwRa>etc+DusUNwr+Q{RRsuTt$P36xf0{ss?xb zP`hCy(4Nb$tNLX0svU2On9*4>I+xb@e9N8t6*~iMUXd)R3(^$m3Cpm0m1a^clX^WZ z6ayM83-mh0es`DSe3b>R-SCS)`^C+d?*>^jRnQRraZ5EwBAETE&c5QD`x;|!zxLSA zkNkYgt=neR6X)`px=J)b!Cl$Vr#~lUU2XaU(x+cf((}Cqmo*7Vz3!9uXS|U)RmujJ z;RGRZ1v8KfKefm-Ty?GFXN7*vfU!u6rsJcvL{QQULqkb$5Xfd2z{E?4xfKQz@pL+# z7%UV9f+DDzuu9Rji6tfMR9aq*!629LwX1 z&TcMcajD2FfxOW5BP}}JiSFLhgru~=_Qwl_xi z738W_2|8kax&SQ?OKcBUCgzt?egvlD2;UP zG~|)f{QWMHmI4h}3)Ex_X5h8|C+|5}OI7MN{i)KQ68#}^-e5%T?dcMe@(b;FG8wlQ z=5u|b)R*(*C9f0)i?d%H8)FB?#!}{bbG>tr{^D!0ZT#QDf}B4d!~wc^@?gy(TQ>*{keRK>cEX46LkYKB4!Cz2_9DUi-CTcheN@+W>kZpL^A{TCL}(#FA|M+ z$Ds;NEEflgXt2@1t7ANw+|FErY8-|U!!OG=edp@_; zN7WLYF}pS5{LQQ;cw=ANxibh6&kA;Qh+m>10VyXbpmSfsXv^^4tYp+irrM~0->Qv1 zR%>KxYKARZwCM96So8sWKW|s>x~s>y<&p00NA3!-#HT+!_UYSh`}Eiy_gsGYWO)7L zI$KYGZ1f=yka8Q)_*vL$zNUGWIeb>9c zVh<00`R1`5WAabUXf~{AI%aXqiWP{oXj(4TFf|*XpQ0+ZVVXo!(A9B+<#+Gcv7HUy zHa0SH?G>+GH4@rxnnfGPOsX2UTTRnyPb7LW>F#)<-D;SMt?OCS${KoHG1a7rml(+# zW|9c8j6NJdAAXR}(@g-lAAoc=7fnsgHD&}AcAwD|_FWL`bq=M37LoC*2<}--ie?2d z%SI#3QiQYsA((qqEj`b+bDE`QqtVV}qB9!Js+N|s?RlxnnquoTQBY?EXri65zFjIrw8)+!Bn~fFjF;?sTaTGkx!4LPH;-j$)`tBkC}$i8n^7C zZs4OAZ7bet80KCZ^fPbfx}#CsjzoKMR=zhHvxlL$b)~Iz#j+x}a0SIqsB@UV-BKs} z7W=qlN^z-(zRy&ukU(hQHmWj84X|t~tCz}byjQ$Nnkryht#=VzAM_R?h8 zGNVz`Dko`+bb=i8{2ba9;{|+j0r5)=BoAcuvvXJF4*IYn z2sxmRu4-QOZ}=;9&UJtt zTK}0N-iY?Zh_hbNE3sj(?3LK_e7wqfXe;T%vUhck_TCVL#sJWFT2|rH3x_oMdguaB z86flHOz4D|0hn`C(K$*3f2IVXhKI2;Zg^MbrKt?Si zN=LkHqca0pv9*!ObQ*7FFMFQP6bM=b@bEGdWjkUR`3MNI5%EgSG27eIXQl+%OPQ_1 zR>3eV%PeBw%1lgf; zPLcP;d${nIOQ)BX%1hJfmKK!Ck)mZ~^?Opzd(z2dy|r~HnapI8$)VQPdNP^ry$33z zRg8G`OE@#f1;~3+-{Ey;okynD^^j@40GZ|%aHAKbe~^AAy~+%{*a3DayMw)-J;DA8 z&%)UTNjc3&QRga8!@OL9$Do@YcYZ=KqbwlfDyIh-q5AXI#q~rt0yg4+fd4?(5a6nEf)6})+Y zvQ_C?_=@Ap81AR;K8@JryJAh{7k2r!IP9+kcqGGVp^JBmmVND4+{5Dj{RbMn9Wj$d zr+K#uAcpOYr40#6eVPMSV0uH>k^K0(+Oi z&;s-gNE`}4fARf{q3gvsH<(~QE)|FuAj5A9!9qbFyaNnN8~p?>3@}!P5i}f?zb(2T zZlVjsA=JUB^$W`0mr*IH{3NqI+ zQzY#*G7$HwDx^NHMMK7`)VCcx=p1FWefwDX%prV8cAJ=h^fq<-?QDm$pFueW$O{$@ z9?~OOu(hvh9Wu04$gGc#sB@SFQeS$i|Yi0=nJd*$bo&4z5M~c@2B{Vz%M9~z zij1Tn(Bj@#2AZ@KaALCvLYzwW4;0`IG6TGtA$rd7(4u$nN>lN8e}NR77T~#IE2C*< zAWA4yEE4HVvE{H2LBzH&(}K=l+ij*1(a3(T1p*rMM;+rDe#V9l$dtv&`m1E zEZR?FumxkVfHC+4{7M!BNxBktt~;c6NDoVoN{>rVNneuwTKcB+J?Rzc*DTCZtjzk@ z1~$U(V)sMdgcZ263tDtKBYUnocq!zqgO@}OJ9vSWgfMtxlN-EKHWXpJambPw5)~Ey zr?(r^B|75Y$oQ+l;l*npBia$WW}H*=SNlIY$KUka_l8O3-3}DL=U;r z`7}6;p1Qycy+AGY-@!{cp0d@8VZDh&cn2y?Foj?N#u=0 z9!%TdYlI(JeUbLi{{u4lA7S6^*v)I*-rTc|SH-@mX5mQltRv^``LH-yRmPjA-_@*q zS94FJS!b@_V_-*g(_lTGPXo+1L2_q!y<_Y$j7*%TuwmX6&TGDI0n-8haL(}V;GN~X z_Tgqnn9Z9rn|rdNt7I4|-9B2??3!HjP_4PA`MaZeB-h+Cj)L2@;&-3ua5;=tM9X`d zb*Gy<&}^pGtYf1)xJ=^q3%7`rMUMpK3Z9m@GY*P+I-ajAheV&jCQydle+qKHiTOSV z&1D&8x|Hyb(-|`b)^(U`$_m-BmokFq1{c9w1z!4Z(69x;I zEW5Y8vW;Gq`{TTDoIX27Um0ZwSfOdzX#Nh5jL4yLA$fS%{TX&9_U|7a8#{Xz^eH6S z(lzj}xeXje1?P=|lK?9O7@2DRGU@EuQ%8?FHT*pH-03M61FOCLTemk0#24}WC-D3s zJiC;jhseN_gmaJC?tzUum#oj9q}6}7?QNN=6^VI_65vy3I@bdn%CjT`PDjlMu18nJ~Mu*~M)h$85i-CEEpnlzbuQ<31k)o^1giEl8c9vGgj)U4p~& zD&0GF05GLLD&7R%PO8L~P3&U__U#xQwO^f_0FFI6`eXb8Sh};j8}i6-OG``l-g0^G zM6Gscs$8BT+8>0ehIi9Rc$Z_+0t}-^`FM~L7PG7N0ye>k%o9HD0n zNZE7$oBf#mHTc^ll9cI#!FdH)!=aKlrHEP^RA4BFQ3h)V{RUuIUK!|Lw2}cIL^YT( zF&m;}R>0v@H1Ofn_T&x0h`jal3%LploFlJ=C zlq#hvGP%gI!_N3pwr{C3$;O@My4fLT9~);^uXRqWWwn=?J@oQg@-aYrvNQoZ=M?Om z1@u}krx&nv3h-KhOHFSHkHM3Z1Ype+e0yrPP3}3uhk{GSY}faR64OVMeMN{c-wy^~ z!G{<24GpocfONqP_hx7%R2^mZ30`(K()N}uH*!yia)GuA&S8ksAt`z8=j@-^-(n2^ z7F@>fK@Y$SqN^NbN>Z>|yh#TAT|5Kf0R74U-efrmj9{RD&_%T{AOKHfV1(rG1H^GY zL>hH?>kJGH)(02CQwQV0Rp?#k1lY>p7eN-Ye;$ryVOxG5`F}yVVGqWg?1Y z`$hKN;aDaRcwbP(wOD{(2>KoT%D8IE&o5jKRVHGpHo1eQ*u~Dr;nfCFplWu8VcNGL zJK#h5Pt#ohsubJ>w$oMC_CDJSGnkJ?gfO~5q#Buoj9Jl1Bsln$O@HN#eq7$o*1fcT z={G+1#C~?@_*#4D55Do<-T%Y+0#3*Iedm6`z5)NKjR*#~lg6eHW`w*59~(ZbnjTXP z?sfxu;(CDhumNBk)2=HF_F296xH&!v-|L2b^}`DTw0UYd7{iZjNzs&!3O1Dz^Usfc->u-ltxyFZ!x;CIF~FeigPdCG1SW zaSI;BF?f=}f`@m!3_8Ry=nzR*S{C9R^O+VUGK9Ov`=ECo1Wi(5c1a~vSeToWh|p(t zRLC|P;oLMF+eF>7**W#vLzPEXzhwL^>Fj*&1lS*dB!o6bz|ZVW;uPmYto(52BM!Uf z>()zRI8*Hl$_>!hLD$uK!~M0-p0$r2J%zu|J;!cyem*r-gxFAQ77z_G%^&m7sFz49 z;kkZ^beVJ&WQbIyKj{w0C9H<8E6&FTN={Ru<|+SRP%$UV9%U=dkf$^ z65iD~UftWA9cE(B-8e(h$_fq6kWSJx;u#K*li3;DUWUJuljGaA(LD8h^vRYL!3bOg ztAdb~yqoQW5=M}z4SycN4yI*=MMKNs-sQro!6rH>1}Ek&+~|nx_K16CwcVLSa-b#L zl1#MVj$wbzCkq8d*}gqhu}nMoUW8u2d#V$F8a#6ApmA{jx!Sfj+4g4J{$R9y9#mol zLm74yO@)t_o{YvSvHuyeRx75aW#i7@2Z<840$haWkOkCG_$;G+5Xxd&k*}xBiDh1l~KHmsswaA7Otm^{1h~5=WxEk0NC^tzDyoCzW5;_1&(BYI0m|9lh&J#;;rxEUY z0#}-z7C4s>LUM|uG-Ko3|Kt?6p|Y!UN)+%hpjNfJ8@McCn1-4QByBk3yr*TM9ZM!- z_CgeUV|Fs|PIGr49*K0NQeBZqJh0pRCp#Lcrf*2fU)B1Rse0cjPym27U#3==e@Q;y2G4`ebYEpzDxEDCi(3|Stt}L)VG}Vs9f>M@ zdRig9f!TggPgAT;_a%jVJA^e&&UAr{wdeC2y7Pl+I4*Q)^YVq^&IMbFt>u^FNbCC5ntSnAdZZ+_e4*H>hl4{Zt*$<5E+!#x}hk*7Yq zJm9H+i2FSt`~YWyiURaJOK$ml57JHa`CcC0CE9{a7V6vC8DKw%(OihG;{Nr#!*OEFel**nY+?&GK zfQxGs=0-^OnS3U*qQl4-dP+NocvUT>W20k5CX+u&a=#`bFcIL#gFHd->78AJcXk^} zCcFv@QagH$%d^lb%YCdQ!)U_2;UW4#y)41?KE;kXJJ=!H{*)3^KE=kIz2oE7U41gl zNfEj4F6YDS{_$}VHCfDlLQ$Sj#>Y?nRKv zqW>ZGeui#p*Dhu}3x7EIIp-%V8(^PRP~VBoIPJMY&Xm*vm==-WGY!MV+l zdfa=AV&3E+8!rScp%{w|@aVge#7Rl4g+qm8A!TL*xJ0M-WGJw3vV zC*V*cmpmaFSL)LbG=KRB9w~nD#b3wW7q%8It<7sbSM~7!TCzsdcd~KI|7_=^34BIJ z-DjM)VuU}Xdhvr7KdmT*!h)eco+lo*`knVIdFWzoL1bs(uD^SkKk`pr-nlDur)`hf z1Z&V-8U}xXye+lzNTl_6+6&S`p%8!sa-a?%OuZ&lG%n_N766~rGa4}s#DTUMW@OC6 z7{^A2hn-i3hj;MVF>FUH5>%{+Jo8&BX`_4u!n)xV*Ry{kmtSyeLABM3l35eAg#apsT`*!|y9n z@l)Ix9X2Pqee-89sj{lIZAG~V@2j;vJ(sq(*VE}m?d_L#cddYHeXi}ILgAve&Wnph zgf0vgix+osv71ZXUWo>+g;+!}d_~El>t5-Cw0uuGnYgH<71TS|24B&1zLCxpol~hq zVxUkOM9@^0bj5UkGTHLVtn2bScy88(`OWO(_Eqo7ytKoM-uFrv{Uh+Dqu9cP8(rwP zR2L!8!z7QOuxZc&yXtT$M|9!1_u3Irxa@>CIF7z5q6@u|i-J^)}@u^bwP^&Vx&MhM=Q<+XLgPwTu_aJH4LJ@WY(g=A+&-OLpA%fO1-U)pN zm52(Z5k_C42~-IJ37x{LOfwCxanUK$HdHWQbO*i_)&d_7D2}F{vCOP?JHRYR2oTn@ z+9q?80dc(5fSa~y-cBAKF?BDmE{k1eYc$qsCe5V(3&{+6U5>Ws% zz!mfk(Rz}uw9(v1Z70Qb?jVn$;1sVacA2;H!zN@F??f3sDS*}js=VG@&rcD3Sb_}j zhlnw{3{-h;SxtD+2~1i{ef2yF-E^05$MgW(#wQJ4ys3WbNyWfh<&!E_geSZLHN`B( z$mt~&hARU6XLu+LhK3n_`cDyq2?|MJHS7cYBm++#Q~&rgNL>K|j5n->wM-1u8(EX<^jtQj7~y|Fl;#j3Ek1Q~Kg!BHnZF+6eL04oFjo0?+JjFiWgnJ>O*o*XWh zhYuXzz5Doq1JCW={q)|wPg4fBrVTmEV=J$hCZtECgVLW$FG+xw-WXShsD)AHYV9k9 zoGrFgp`p4`Q$t9aB-*2Xrs@iw1N^1ARb6G4VlhZUcjFY?O@X(&0ky6~mvLKj+jci= zi`f7lFAdR<;3~*n!NUvQa3oconki$hy)4i8gG> zm-N6fUC|YMQRvZ;LLzhg3$CK53tPKz8X(7)$i`DM_tK4_A#r2P zTjrNoLU#%85z%V+;^{}7b(iEgkEafcyX@f}`*>_F9e+Empc7ps4>?8VSv7X>^;M)#@`hCGKaE2 zL(~xbtO9@_uYh~sbec#c8IePyV6(FjFWMg*4I)U!QgEJk0#PHh6bg7JIFn#!gs#kR z?xmeBXY&s4o3Yb9JU(Nm+YoyR8YmJ?V#KMzlT4P^Ai;{4iW0*RlEB9hsWj6p0v9~7 zA1BBd|Kv`^s}LnrgWu$3K3SaFg?yDyVJE_@e2(3Ch}~Qz_T42NX5|a*rSav_k$Ipa z>qw616e|2c1>St10{+1PYXbO2!`1)cI3*YrymO{il19p9C=jstQJ2xNlkIurj*BDx zTE3n0`B*U;$yrJ`(QYE->QG@QlP()axX^$M9mCa~2-33hk$Z1@io%*0CUG%-x@S|d zSPleW5#H3pWe&nzKx`RY4bp?TEo;8WC@W!$^DjK*Lv>v~*Bi#uAnp8WS zU64#xEZBORI(j#x!}WOfTfyCbNBTG-y#HMKiu7&i6>y*=t1`+#hzI9iVb5*$O261C zcxjVH3dSm)zEXFieBEwAun={Y%VzvC+-{o+dEY?p`E;QS+G0%2s# z2$vesCX$%)N#&jaTZka(0>o<6c&lzhg0j2xKyZHXMk@_}HLzL zZ`d~7Za7NOo8-O8-mqNv zm`Dq+1@S})hj1>AQLUVHVWj3g7;eD;Pd;jFwy#G7sZq4KFm?U){1Afbj7Z?l%`mjW zNCT%l#x}>=;O%6BkRa|3Rvj~A#_``s>j4U83Yl+Z7fhNO-X4z%;Z7;+vi};WdS0x~-^s$oZnb8d5?c#>=fn zF@sc1MPw-GQ9v34c7FiaJ>`RfY!7p0rO^o1)I_Dhdeb+365s5pU3q-j6Gu)SIl0U^ zb&8cCi-QkK(!H<|ZG^>iOhSI@PQPtU<<84u7Kq7%nT*M`)Q@{pZg0Q*-tkcdP&QbAzy8(BN9mjM6imeLVi)PTrNgl zQof_kUZh1aBS<3Ko`{!BDw(A?3wven_`h%m4h$Nk`e2Nw_^`N>2SvQ_W84P|L(D?1 zH^x1&rjPH4nkF)_w40Rr;`K`8!&!rE=LBp!^Pv-wPvdQnKkt($dQDIiAKEM^jh|>{ zc<2Q;;X-ArRWo?Melft`o2t)3f_dV#J^xqk3NsVK0MvNuw2h&?s6A-t+=+oMgGhWy5w87gLYlr{6jtX&n}Fg3M* zFMTkSxm-Dbe*PfxEe^p`R%+((b~7zf4sRNz%{;iG*AWydq69ETDWf;T@LbMH=)DR% ze9D(ykr$cBw8+cOex6_Ptg1sO-QgTUrnCv*4Yz6@{Oz3a%4fM>n?{0q4%ro#IVW}X z#0gcWIV^Qx4*x#*>sx3J_baY?*_?e*W>dN*SCmvdR#K~DN)Lg`w_lz1ot7goz(6*LE8!K}Jw22R>C`&bCMY{7OQ zg|dLbg3e=~M4CL`p1_H}#5^K4fhxQfC~P2bh-%Ru;%WF7WQT~RHT}ytO+zFY5TsPK zR&SJmOw`5>v!jPch7rwtpzz1v|NbA_AOG6dJ}%z>?TC;5DB`0P;1F<>U{#tr1DG-O zAY9ZaM(Lyb_OtGNyLL_O-sil^3j2`MMtjGuUCsyD#9k5W)znSGXdy>-m>SHDBm(^v)`u;?4}C0OggX8 z&OLY0o=M!a=W|a!U~%~PNWjr5DLz>{sYKW8#5Lf>j%>BH!-ws?ds)q%y5rsEyPTu& z{yKUharp3oy?bj@_Pfn@-+baIcLzh;3UICjeBvpu{SYD_-X={+e}rD~Q5#oS0z4%M z(fOViE)`)=^7vTuQ+ihrn)4))Z4ATFy$qhhNAIe0p2vo~4RhrQKd6 zrYFQZC&j^8XUxcA4`H6ab8pW@=Jre*3pYZPEP9t?4sdJ&NBV-f2ME2L1LR^xHCgok;fp zZa1JR$@7(u3%s2M?2L^}e^OX6o3HkF+3zGL7*Ddv)4uS8F2EbY^6$3R;kStC8J6Gm zE}%+*AiNjrt>4E?{b~7c82L!Uv4y97;i+SQ(C7*6G|v%(0(@xL*S`+ttDz##9>eW? z0%KO-nbJ)(S_NJJBr<~>#nZG5a|@){@1}zZ!6wdbV~1||$@ext;5k-2a2X=*Cf*T@ z=sMINSQ#V1cd%V!M~{x#BV<2@10HP1Bj=<8lvbX6$y3$=>c0YMpT1GTtGFc)X91*;xSb6_C&lK_|O?=sQet3 zX_$JhTqA#o6Juk@DL1s6e>k2(mFC)Sz6XVr>r@JRu1LoP6f+R_GH2A$3tl@6moM=k zVE+DzW8;fKfjgSQ9C<`I24*8UUE<(3}Ate+C3KY{x`#=F66E4VxM08Uu=bT~Na`^mqm{Q2F z$Xg!{&I<+G>yalpCHF0+DR+c|$A^PFfHrs5o43FQ&?p+RPQe&0;GeB~g{)FAOc!|P#$Zj_5i z(Vb;`ZF?`vCKI(Hb|IdCn!j@;!Yx((`h=H}bbS2EmDlUo8^BmFr3m{s_Gdh9ygB}m zJ)YG-^T5*K)@64#GNlA~a0T??yg%&o!~gM%6=im)?CgK~S?AGstu`#aLqlufgVFZr zqvs@;g(Ul~yWn0=Bw^NnyaG;l6R_<)1^==Pn!U);u$w_Uwrh4U{TAN|E=SF9KvUHfr(2mjXSTIZp)taAm9yp3Hu>b%CT zMDbr=8XZEJ`q;xCuYnHv9OYYQDJV7g!pRC+o?ArE38K;rD92WmSPfuBXqg~sMPXJ_3!e;`&~0Hg%@tJ;^9$XIA7xMT7b>{!-8{SjiA z$ox*QgS-jxNT`IWrDg3n4JR*f&Uzx1SK=`$kT*|2-t30Fc|Dd#+YUW~a0{31Oj}R* zKscW-RYhVtSJw2u?m129NZTK!u}tZHRn`vKd)lO-$ekB5Q-aHtUWyy0fy zk!FEC3g&34r#NdH9_9@26xxxY->7-ac7rEIfX=mgVn@&PDz*=W#>-x{Kd%d9)VIrFt+jXIoT(6VC z%SLeS>*xQ1+Q$=xq0c-UF4@zO(dLbLcKAs=WDl@}3%g8sQ`Reu?M4z}Z{~ZY3+K&0 zYy(Q-a!=FmXMjAK-u!(g2nmOVOHA=>fAJxy=l+aIE3+Adnh0wd11 zCjWHU=$>?b%)QLBbV_q2y z#W_HnU`s9u{bvNOcndF6^oDunofZlAD(>F|YQslA@?C=nrlb730-5t0%LX&96vO|d%zNZun9`T-mfJfae$yiPvxNt`3Zg6ZY$rnyR$ zvmtTmrq~XO#3kwq+a2vM7FQMv-3U?!OcIfUW}9kajiENu+>x3mfNLSyu7<@&isYFE z*biBKn64ost=#|$7!Dy`qQyF+v}o|fgkuGQo#*9Sm*?|6rk2vQ2#6004Pi+)D&QG; zrcy<2joT%p)x{plbcFhGXV71bI3P>rHtU1WcTE9D>|zeVOO)$T8smyl4qs&L-04Ys7Y_9TgBbE z_Z5Uj9e?>15Bu^JF~?q^0ggYfAYUs~asI!CU;4k>x6M}YNbhCBF6EN~U3--?MGavC zf1N`|Ys2;k{*Ml=wGZRhx4HL#&1sn6nI3*cap{Cv$xzl^^osO$PGIfT{2weJ1S z1e+57w=t}13vmoytLzz4$blr_2#`HCPOGzs{IkG@&YcBj@C}ZX*zU?HHr&6eK?+4r zh{RTiOlPM~ojG$R{Nv-twHNR?dHgt=yke{K!c|wXr9tPxOIhJk=ZCCk13upq8+heh z25*N9{y1=6ihS>b91dYBhJH zx=YEG+~4W_?8tsH%Ua?69+BS<7%UFR!?(-XtE>BI6yXn>@|6)wj>*SyHK9Df#EF0+ zcxDmjDDy^vr*hoI;W`8#k?uCeoFrWZUxYi6qiY0tj^8OwN`Hu_q_5ahdQ zJ2@z_qjk40vp*6pUX76!QdJ^K!8#bYsOpd zzyB@#5G*_}U2O=j4+gxdc#otT2!DqHRwP*gtWn5>Rs0A5k2AX>&!W*A{nv0s; zU{dqcc(&-XJa-%SWR#zlgP#q`N4N37o(ex;^IepwRg)`dG;Wlk!xL0ZDmaZU%e)9em({& zBK*AWdf8oAr#c2Ygqdk#ft^T{9WzooB5Ju?@(>;|X~AUyR>&JoApf9M81Ruw`quqO zI`oE43GZiEp1G2~utIh`)ssqA<7Oq9>d!p~xK0Tr=BLuVnM`jwH9rxeL})GXY7*6Q z{i$Tdd^+9DPbjDUlM}krI3ZO=Izx(A7CJ+m`x~U(1&2AcA~2}YP@7JQqQ~oJ?B2C4 zEp2Lcs3ix>)h9jyDWYv@p)i!y)9Gusu$$JgWHPyQUZG7@18aBgEbZGjf`xeddkU9# zb}eF~80$IM1JA%7NI7jOC$GeUrC=&iN(c|3nSSeM*zq$jI(NOO#p7Bt7cqO%*~vas zc0S2&nB2X49}Mt#OEL^T0jV9b@@dG*D~MwuhA88@N4j1H0_mDY4nd1;L7B-2>jKDP z4uRyl*%bZAfuP##ba|6HsI{e1wF1v2?k?&?q0N+kC0|RW+O&o0rZU#U>BzP$EwwMn zwsh#}sB@N24WBuZmWRD&U0XCs5y45uY5`<$%UIsxKO!YNWEVscceli&ZR^5=t%LD+ zG7-1?iwnZ6`$FM$!uFLwKMR?Ya{LH6iW?vyhk*FepBy{x46)}(OhWb+NKj>hw2-Fd zF!Xk$^2ddD*hJMag?)3FFxf4TUdQ0=J~49+Pb2Zu9VzCitDesZz6J%MgDBCcBWDWt zCtC_1W>_Vg3mj(#st_+owE+p|vMrN1OoJg{8@*PKRkV?GD$xoat`VMAhe{nh&j{Pk8$`pl+oqk}DXzQQz3PMw zuK>Zj1ZGQ_Mk$XikziK9OqpSVZr=?paOmbVaU%wiP2yhO<(D4ZS>hPfBqI;5G7VFZs_XTP%ISjoi2UX ze^a|>pF^iRr)HiZ&i&^Z_s^uqr9WdgvNnuV*u%t)Fw?w|9<_6tYHOtW?5eJ&KsQWSx?2EwAmYYuD`@{EfCMuz*T9Co^T)MpQj(|{O59|ARjRo1gAdd z`l`*=*~wY2i$9_>#$VH{SNCD}4)}xlUKoFg^m1Egy}0IRqd86E@sBVbBlONlh^OiC zZ*GfEx#NM){aNqq&11z?w{<3YqtF|f-YE1Q&l1-kU|;Ztp*J+q8`HzkdqR56dy_kfWalOaFF9daZ84r;3X85m z&#`hkRw+RgTMRkG;L8@{i*Qn`i&&+^(^!1#9P<7=_e*rD+n=43Q=7b{8~^3~nF8cM zJXGifv-^{+#!`>ep*PdgFz8Uae{?8Pa8QTlkn1HzS-89oO<8ckMK0R&I}{N<(JAisyx`9<(b9R})lg)|Cp=NmCS z&!-(?Ow9>UR|$mTNK}fuumFc@{xSljU<9euz2t4o@?`~`V_5i$rcU|IqA;vx&yVUt}n>}hfKO4k{S^O_)9dXJ4CR)PMt0-;dK!=D%2l69) zgZ}W>zg~RgJM+Hzv)|a|pZz+<%vkKxw*6`Tmw1GPJeUFYT}T=+k~K1Q^2)$?1KCGb zI;1kj|J`He9lOli-~Wz#AF;P>yZPp}pNbv7c;7qjefWn*w{837v72uO&Ly3D4RXd` z0YNLk4~25(1I=u}_QPF#;0^+B8g3Y>SL>yWO8tkBe%?#m&*s^CYqfjr#~!GPd<5H%-%Y`XK-tG_r0;$!w^l$ zCnmz4hOd*r4Qcg=612=7=^J><(=Ub_eF-r2;u^S-m+KuZBp3^&5J0yOYsirVIq`?e z17P}M?LLuOhh|TI8NMheh|C0-OyUs89IeAwt0M-jf6#SBX*w-b>sT1Rx{RT{IyFql zd_yQ*)EE*)Bh^nDO$?~Q(M71mbd|yMK&mE4E3@v!=c=phHP5oAzxd>nPkyId#t#jl zGa*{-4z6Wbj3Gqpk^zUo2MML^m=U!RtSENCI|Rq6tN<*FgcR8(JUnbG2J}jt4M!9L zbOIsl)hR-QoaFH#Hx%G8Y z@dq0jv{ePyMDP=w_5wPbVbNYpl@pqbG(X5Kmyp#McEM2=;ZT6;0q6%PE((4x!1S>| z8lt=?a4HxL0a*zkwmhV$@UOy>5lJP01lPC|VE$%6Nuq=&hP@7Tv;aAzM9FD}98wT_ z6$t4V{)Ep$M`C}@j-u2Fban~PYz}3E3m{FVMg6bBzbWmmlEA}`s?CM48^ONj8jNb= zd^t+USAS>M&Hf+lz7~tBwGJf`nE+eSvTYd4@)d`YiS%1{zjb5CriGT*zqB#YuOuyS zqea)|7TUBtxVIK>jErIsaz3wx8lakTE5YW736Mw>svR)+bp0F>z%vf zn+NQoY1nf8VknAeWuJlJ(yS4nCKhIA_dHf@BVXditeE zF6j8d(2N@cIb;2Z8dtn4SXP4Oz#x1qmXu2Hv1n;YiBh`daq6KAd?<#Byyr5B#8B&7 z!_iC>!Fk9=V9Z0%Xe&^cYL<3}^H?4^hJ?bG&W{wVNY<>7mpC#PaNqEX(Gs!pQHthI z>93WRq-d$p6t1~cl$Mr0NWI!h33JoDe{s!Z8pK##s785WgSK35-Mm6Ao#`;6*cr3t zVJVwd#K{&a46BcV_QDuR9$Lr;!s&4iw!tt48jZCqdjXh71n5T{o~XBzPF6`>1VWJk za*luM0GZ2cjbdP+!7*aNp51hkLZZU@;{xou(6QG!^zHlKdgC7Z)~#D_T}<({NQaKx zClRd6%RiKGiK*`CRr?fZN-t3o&FUP?00V7wDG2!9=rLc zmtA(>+h*;+m~n9cSkjMT!GTs>b{l*{#{&|fr3`_X3~lAdRIwj1M<2m8@#1504d#Ihx` zw|O8uO;FCnp_@+AaT;MDx1hUSO*%ep$N;hB)ST8$B|7Wxdw~tn;;Vd+idGQGFjp%o z5f9)07Qq z75Q-js;*uK@h_-{^Vg{`is}kd4YwG?CgAQ0(oQS_%tJPU@Xd-FHkOW5H3ZmmE(CwW zFpQ$0zaZ3bkHG4o7GHb?`~=ogVl9Z;(gFzDjcO5EIwTA#&v_7;X2}#mO<*p^fdf7U ze+;BIZb4oO(IioL!JtqRc3rGO8b&*S1+g?J-4$H`wqdN(iFQITX&~TN2?d-VJdD=i zGM)(2%)oK{cWdLSDpFG@W+cktR^EoFfHtsXY}m>I>A!bUZb2SNg?J52ac!y+LAWxd zGzqH6s){J+U=)im<5_|kQ!QGAmm?oNfO4y-ni*Q*1Isi=gA{dSBHRb{h&}UYYb;<9 zgl|aD1VV+!NN7sd;7fsmpCO7jt7r*4FQ6(DYlh;ISXvc8G5o)Srjlm(fvp@XzuAMVu?oOkF z=n~+~F|6*Y1QA#rVqs0i^WmekD8U$v`;ZY}+n2+!pqhn69+yzHFq)*)3nrG~^VR*IL$nR+)oR}=}SP2DrR1_n3 zQ7)2(vVbJ|Yq}^Ge-S!s#$umoE95Wf?!F{nX!ALb#bW+S(ea zWY#M^Rv5r~s?gjA3SQ~ONl1s7;M=h)kwQqyKw&#Jv2(J$A<|(s+E34FiMRRitd@A2 ztVkx=P|!O@?&OG=pS~Y@e__1A_3VG3FRqt%z^1-m`h@gJ=}D}r3M35E#!ZMtY#JN< z0mam$x7swA&pgs(j>5T#@c-IS*MRHXUl;MPJeLWm0kzeMwgpRF#NDC9g6m3Gl`e;$ z^AB@h0A;9g!6l&52w)X=Eba^3 z1$PfiFKilC+K55BQo?Z^$sjI|#dc)DeV7fs%m@#|hXT2=!aA5MGJ;Q+}4fNF~oa>=UzneY4dWkGYfqxNyHS~NemdE18k8l%SjH58R3UeR42UR^@Tl2`^ zn){sZvsUL{fAbq;he8Wbg>Q5ozW^<3a7N?KWIvyq)7~I-Ej;$$dDO_GXR~M+r)!om zHfCJ$wXa2H(J+2Kdvq2Rxdw0O2O1cLvmJ*lyMQ%$x#uWTS zUBu~LbcgLiIK2qJx~qLiuc@m5kvTshMfi6$Ubfv(8% zo`;MF_eAUp9^RHSw%wb9lpRtg3pbK@d~FQ^UZfa}wnqN}ES^CE3?Q{gq_-RdBm+Pt z#FolT%k|oJMz*1%A>@9~gT_O9NVEgA8%jhYT^Xcr0uCIW4BZsT$f3>MBqt&)GZ6d- zv>Po(pjBcj)#i~fPqq&xwX$c}LFpm%hM34Ay&}1@y9#V`5cIJDbPK+orqy&;onGw& zordw`W&m|1HLgl=RYwdg^eg|0fhSJ&S}h|Bs|Ni)jdfGh@6k);>yD`aQn04NE%(u) zX(YGOXdxkt98J~W^XBtj3bKEMIsoxXtZ7NA@oB7EM(frk2zCQ_M#?o*gBQ$WVMP4n z18J8%0LYhrEL^r2!FY!AEB}P$TQQ30O0>);4JWQbVZc6bJdX~Arb2m(zRmRybTt0pwKcHGBJu_&ogZ$H*8E(~$ukgY);; zqrZ0*$3{5pO>Vg0q<;Vb6F{K$ZRdjzQ|NCv@FJXZani%D#bRr08(+4N9INPq6)ZQg zr@LCo8woAJr>GVF!w55@3@%95Bs=eAA2#KvuHm_XKSX8Ixr_T$HT8)i$ED#725vz< zu_=yB(-unD!%<+qvU830vGwlyN zzw^i=&IcaBhx(XkWh;9KV?Bj+YpNLh$hhXhJFsZhkc};c|1!Zl&?Rbsdf-SQ z=G*VTapmpieJpm1{ch)rBe&ka;@MI2Zks)3y!{5iEVmo?#cpNxdwzNEsq;AB6LB*ec!@Nl(){jQip-|K`m3_vXF% zza2u39sS$D0wSSA8z`tJAVL{vkN@FS_STjdRu6_0g+yEsq^$h)p494qr-Pqetkjzqp(5zDQ4HRP07FK{4`4*jA}-+(nSe+9QsapI2ko>o>ZLG55D0^I!M~s+2LNfL3(AgV zx(O*ZEdPJqoq3d8Rh`G{)xNx1UM*cqcUQW*l3ufPcXfA#q_cK)Hp7~9fQTW1q?15L zG(-|v96%X~Fdib#9FiFoIUE#%iU>Ht%%}`TRD$S$3*!LCB`!FkMi%Zci(&W{_b!6{!S?o(@%PZSym#A^sET2_ncffP7{oO0`65j8?gi^ zXeV*Y5BU&}MTdi01)~AGOkc`UXOp(MEY%>r$SO36EO#iBp#8qUJ&+zS!P?{TChjrR z+C3_k3cm=wGTx<3kxysTSIq431Qo#5cd+pF8Yfrd?vylohJ;#`HI0X-W9krSr;4VE zsnY`O1;W(P=F`7-yn?OHjm={%^g?CYwhm#Hbj76+v1KF3JZ{0|JAJ%bkwMTPTL{g71(mVfh}j3 z;~~d!V$;9t_^rY8XM1t$_Sz$?r0sOJr#+yt3k}rpb@Lz3pa#0E85gZ|76r2sB(=zb zfls09GR6w1QmccFRr}nU7b(cD`X{ER()zJDIjZsVk{L;8Ge9);f@Krk|4B-!c);7-XvGVD!pY&3K!gmylz_#9 zNGr*}J^n)6YHapazK@-d?YWoi-fFes7kNgrRcqTkP!VKrkM@T?;||(nkJP~W zE;f#Pv2oPmU36x(c?z!&t(S^@QLKq#S86{Vtk^|zlQE0eHmW5bwtGqS>=03QL>vd? zBhu}NBt?_YD{p(7H8Nt{QMnrd^^+qb8_MO4d`Cu_UNV+m`cmD7%&p~eb4SNHYK+zB z-MHhsM!=Xb;O%FWWv6(bYoSrIlyv72An1|(Muatf`w-c{)ay26S<*(U z2^kZW`r_Fmjs={6wkbkm!@0{n>84NGWaSc^qeI)2>z}6P2)^#e-ALS^K`)!+o2NvL zs;M~WdDbx0+>tM3GVKw?|A^Jnsq~_t@HWly8ZkDDjX-_m&*|Lmazi^BW8zi-oCG@Q zjqq&1uCl~sWHZ&YmjG6I#F*JDve`D#ZqGwQj1o*vrdTd2anM2pp6yr>jE(A0(UQr9 z#E8TOe&vKn*ZB7W3@i|Scq}ld2fZ7_y5KTYa|lyeh*F(1D`k!ZatiJiN*Ph`JceH| z=`AIxeQjw3#sQ>@8mfXU72!eE)EkRLJG0z6%2Ar54ajOoV0Z`C)-9!?^KXR-_P(Gs4~ zB2`)cG-ptciw^?=y*w&FYSHWQ0{Gn^Qlg1^(ug&Ng2Y_z;-rr$y;SXC1aWgiH!v}#1z zHd*3rbZ=K(U5`*4Vz@y25PmYqLtJip6KG$mKiQYUoWl^C-Uzx3kqdSTh6=CPxj6Zm zS*#TBcNi*Q>g2gQ>A1==X%17-Rxp5} z(CPN3Fn9*>kdbJ5v0$mU$uBIV;PZj38uAXbot$yDrc0w)= z93N0He}bXV9rDA6GW5V!#*#XV=s#_GjJijLp(U(4&2##U?oaket9w+#U(fr_=sPl_kFiHsUkOQd)C@9;E-6;n zxU*)EsjG8*;xg$!~B8oJP<)`_y z4&v7?Ch`U3YQ>+W!Pc@=U`gfT3 z=a6yLr)r3pf<%)OY|J)=f2oi$XALBiX<3?87lA}Pi^e;yMf-{B5)TDbm;NdzYs2zM z#IY{98e(T{$tWts8-;gMTY6GiOloecYH8Z6Q7V(Bu+BOr(j=GNBXGi!5lSME#g*+!Vod!>Fv&d@T5BM{&-)8f<{JGKDiDXwpLpQ$0(Yp>C zOCo6=q91Ee^sc)&UFWFP8_mLtaMY|sh%+2HYj|jJ&sm3AG_CG*x|qw%Po~;qm0#v& zd8t5W|NLhogWobvL9q`|Q}^!&+|to$;da1-S5eg1)MH-5?~iH#vw~C_HR$ z|5-X!X4-x@y*PHmLrOkuiQyAvk4)LxH%fxg$BcuOlSju!VfOO<$wYG?(V0lLqT|S4 zciq4!3YXY|Y<3T3J;GlDfCY1|1RS&=lgrMO>Esav2)L^mnZlz zooflMw>msF*0vyEijet(x-Gi$ShaFrb(e9;gm_$Vu?SZargptM>iNOMwmn;~p4d6D z^QAo#6MGKnqdo3kEmLA}sxGK4vU1DhmTG0Qy3ki$fQE^mw2m>$p#ND)#QPoKGJlc? zoUbFt)sw4wGB!ospp#r{HIWw1Y*A}UEgRv_W*ehouGLZ<(S7yD;+}TKYLzWypwCeQ zSzs>cxU-Db65to`f0`D`k@d`lte5c4*Aix{rkz`AuJ$SnSqCH&o2?K4G<-8pPm)5g zYs%h26i+mShZo67;q|$q!=-?Lie_slKriY=5xdxm3t4G#Z*HVW=p9{kd9Rn_T_!et}cRYG^Ij41PEn!%IbVgCdxA$Ellhqx8AwYavwi;cTxD?i(ek01jFbG)gxDAK_p@ zy}``IjR*=er)m1Q@9FdD{kj$q47N4%^Z2-UW5ff8&W+%?=S6(2 z&9BPe!{v(rw5;Vl%lMG-2|SWkJ1*x<)yA^4>_X@jS&GlG7014EHbSsS{1_l)ho~v|c->2kzZHjU`YzMd(t_D}%&$zI z1+ySFT;^D8s>eFawk5$_B%BLXj*@ps4i%d?$p$R%<13DRcKy=Y8SPdnW9t%S%XgAd z`yYu5*a&5uWGCvZ%$jaNnUoDtYiw<2cHOxqpNq|BR4EtzO*-3e8d9kSK@M+>;H{2W zsn$_kWW!)+m&+y&stv)z&7IEXnj1vmKTvQe>;yK?=j+)pGoOCeq4|D)4wvFGrmj)1kE+zb%MtPlm#A7 z7tJ0JcL7%*F>=OJ=2Q5J+++r}ykNfYCcpVt=G*gI^IN;G-nMt^lKj@@OMe}H3XhGO zsqk&{g)IT|y;Rti-`2Bt>)x%umnESy*vOA!Bj1Fl%Wn9SDc*)mTB3H8X{d;!wpLiy z6O3j(rtDBUh7(_5R41cl^fFLxVmTLdhd5>D*j)FENhV(U=4k8_N7h0&9kL zE$CJfux9b|^x<$uXUK&&jV0T`)CvV6^nuC)iU_HI_9MmOxB^a*wdiY-+DU~c&%F@a zXQ~~e>Pa--R;axe6xyyr=1)4E!6?~k-T9)+6E$(%^nuZsHW_ahhCbqohD>s4gT&mO{;}~Y`1ZoHzXciTy^arnME4oTmmS~cxenUc9Z3I*5J^0i zeqxX!wUFY;DM~a+lEfaRXpK0~X!gF?QN`4;tG-?(s=0-dzD&W+fJRm?<Mr8S~z!u{AjP^pgA*axl=2hPa@zlo2o_*_ZD z$@b(Er#UpsR)`Ja9EDGBOj<7M;_v7)mT+s;3i#Yn!40&#-@OLJi0e&I-DNg-z0iK2drc@E2{%RetybX0+$7X4ICoqW!`!3j zyp4scsfX)xw27xfM-*LW2y5J92VNMC-wE0fmxx~_`Rh6o9 zr8JA6m{rwzPS348PqxuOTT`YL%#R+UXD(qct(m4a5Vx#{iD4@c6GW8T=H@~m=y}-7 zhP<(i5V;+|ADNBl7|n2#b&@p0 znIJ+eJ};5X-8f`+TXW5Y@s3ywggL9HAw@ceRLY8V#GmhZLrd$TTy9Zo%Nu$+2Q4e^ z-Ll0Sx2(a=TUK)1$Ij=#4|=U=bbi~MmHGT&HanQlubk61KN__JY74H>;fNV`8xPgl zylnp*;VL?60K6(JQ|1_=QpICXilY0Dm&}*UyUXRzjE<(@vX&wNaNZjnmbS3~3RwaatFx6&pOGl)Q-K~u#w6N&k$`{tW)%Q71y zXDB|@{Ce{&tLx)$tYP%maG;D^to%)CB5p{66Rc96q?4pMA=@Hz|4lc$Kh|0KPz`G; zX~pL^suS@H#sB9u;~-c!1xF_yKOR*DsYCZW)PGfRYu2M_Ki_0{-zfl-HnMbhOcnxjll8cK7uEM`37#lT42`)flZ3nTk*;BI`#6_ZSOO(Hw9w&O|B7$uN z+3zU$HV4O!Tz6d_-;UNKDv$uCZ43?I=U0w=HQN!vG(JC@SrCKHmW}iGEwAi18W(NY zuwkBsU>%PtM~0ZuQrTtf49#vpuhY^I3VMyR=bzT^=oiGWeU&$~5X7sU0@Bl z$s~A$z238N8Ce?055{bx*+?oe3KR<|?v7BWWfEfy2Z6o^1E;c!Dh5SM?(L{iba#dA zI7@pWY4%=n<|#+`f-(LPmo1f`0$jzSf2$bYg$WjZ``X?{!n4G#EH1tE*2*iAA(6Vw^hSz|IhB2+ zRaC+`Fqq`4Fs|<5QDB}T6>FIXuz?gAis&z`sTnoPGn&~Q z=!D0t1J?{+T)6>V-+trZn}!b@Fb-~+ZoHwCunokuTvuA>TdBNbe{plmyEkom`_|(A z8@_e=-IF>HZc`0^_={1c+Nkq%5G4o0R`J&VW&D_T@Bzm$qZ2$LqzcXX=_yt-e@IsC zZ7@{zBf}Q4sukp==tHJVdD;a)Pk$Qs*2c@`%`Owt1TEg07iyGhYa&kvFEOAKB#jzD8c?Ae+F$QPI7p_i9aULx>_0! zDohG!y6+?gh#<+Y`%2qS;X17b8ik6GDgYVZfWjNWdp0H%m}t zh@fh0`na*;7ZFen2aW169jr}&TmYM^@bF4!^NdooNj_b61j1o)I`=t)P)%aml zE0Xm34RYNIM?EX#4>A+yA}TnYi#tV?#ADzwBBO~9b%2m}w2r*K#)V8;>Z2bDLzK74 zm=rzmY_MrRuBgrxO==#1hR~N8{I!H6tVphBhN_TvdYyIuWtV?6dc`KHFX0v8HEBxq^%vfL(QV(m{leQW z(mLRT@euQ5Gng*R#QHU-Dtg-uAQ3}ydG!17Kt*R8X@@7zXfD--ASQEdt7b4_x zt8@+>BV84t%yj-mi-ExMPjx9M*)fPSId?$K@sV)ZEQ^38HLXv zo9*eJVU z>1!0V&tZ+{fSI7HY91kN94VKXH}Tsc@r8s-kbr$T$Z;p@IL+2N5$Bv;d-x+*^R992a^ zp1fAe!c-~?RS=;5NF*PX^$bHrt%vimdlMa^x$(K0j`@~Lj(Eshv7=pISvSt>Mo6X2 zG|so230A7ujq^zR2~Cyu53!jl3tO4{C1I5J&O|$HBiWzbykw(T461h^H{p3-oGVEb zRnua*gK{QC9v+F9&xRPq9`Bj!L7sxN*3(J<(Ym5Cx}qeu(LTl@XdX5Ps$PLW1axQ< zq<-&97)YXD5yiB`_4)3(Cy`7n?e1BUOvdjyWX0n{?Q=>b3^;V?3A0$NevL=-Pv=te z8`7PTNN2iXek%8LzVf?xXEHe_9G)ZCDBo;q{MI|ofucDuU=|0=0i~PQ`U;^Jo1hfP zku%bX8RHE~?Mi#4cvU?Z=>59K>xo|c{buAkHLkL)Ca4olQzvVAs{{+D#U`k^Y~IdK z1!>LavgM8|1W+T1<_joQ6BuQK4vDOmjzob4XpKhFL=(FITCpx?P@RKHx~NNiBGQG* z$+NDfc6GHheNLX+n5GmG0xlK}1dqb|y1=rN7~nuI>hc+v)QK*WuA$Ry6Ivtof|nhq zpx>LYs9o>4iMJuvkt8S+lCPN_Vex>MOc(tlLV8;Ft69^yI_oKo*o&ncPNvpsln&3G zjJWdtrg;NOXLf3F*6CYpMhb#MbKzp@R3Z_3ot+W{ zrZ_aq*suvhrvRQfFC=Qif=xKab_c(5J z{0$uI-B>d9IMiIF57u!CyQ=m4U2gS(1NtjBR|H`m>>kVSRp~33ao$~5W!cy9DM&Iva+@XjfNH?4ejeg2p+3jz^!QEWP^v zk6jua{!d3pg1;S(XWzH|9ku_{FC)Oc%(`FMlVu0T7%xLP)P~a)r^HB4{XA2@DmyuI zkNTqEXsD|r*Q_2Z$H;QEzWi5@k#o0DTUgKTfXh(!oZw++GFjvw?Ek#>wK*98(r@1f$oRrUO)H9ymRI| z=Wm&RYJqdX>;;!Bcu()X-sk!WwU%aFE#K59~eS;4Uts6Q~YAXHx zLUZA@3-3Ftyr_3^eDQsYzcXwOPYl1jM%qTMFV8MNGrD>7#?dEMeP{J0YvOAjTzBsq9$fETfBV_*Jtuz7 z#JTQsZ$Iz6^PWE6dH(PP?hAgmVbg{u#`0tPF1+ZXYcG24;(y=#;2Znjc>5)r-gMwi zAK!A`mY-a@{nGm`{qELVw>@*&&}DaB_QK`Emp`&Svi+GIO*`(`xp~(^yK}pryyE*; z_Fwth#KU{;-SZmnMu^!n#*>oofe$_Ob)Sgi<2F4s94+jXBcx`;@t5|pi|s@9vYX}i z+shujMOy4-FS_(i_HvMUzw~4ZsExXnJ7P$8L_|yE6qt4qgZ};U_y?I_~-qri| zUUlV;KUN<(cLz45w>c)zAME|3wO6UO?BiZ`a@?C$3%Akc9r(PoI4(o?&_YbG+|k(- Nxi7{(cl`%H{|#3vvLpZi literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg new file mode 100644 index 0000000..13d9709 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg @@ -0,0 +1,212 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bc8a269c68dafaaf5aaa7920e7a17baff0748360 GIT binary patch literal 58480 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 XVssBJ#01M7olcSaV(fF*fAI6)u)>;0 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff new file mode 100644 index 0000000000000000000000000000000000000000..c205e6fd3cae5dbfd991d499c7495c9228a804c3 GIT binary patch literal 58556 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-icon-black-1.png b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-icon-black-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cd702885b45d555982a9207ad95cb571016e437b GIT binary patch literal 15510 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-white-32.png b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/codemr-white-32.png new file mode 100644 index 0000000000000000000000000000000000000000..0201baefade8077c9e1e2a1fb4871d9e93bb471e GIT binary patch literal 1254 zcmV+_)5rR-bL6Hgy3Xl>B@e)fxkyMCRhmee-h*%*nHeeaY z9`DZX>^$zBd++yA#72p|JG&c&BTX@*Gv}OdzN_!v5f}oEMq}%!l>3G6&%pC`JLk3$ zkqkVq?U)yhF;}g%^{J_;WKd1fkHE~b*=!!%vSrJ0Ddlrg%2^@AB!H2%_XPj~P!Lg* zh%P(lzRR-gT(w%gB7~q}io6R^6iq9o-nZ5+Ff;LhAR@BXE-0l=udJ-h3~kKJUZ>M} z*%)(i7~?KM*cfvu>vUdWW^YjQkt9h@I_IK$HQos4T$Jbe8_ZlOHJ_WC3-UaFi-@xO zWxfs~%F;AFH8(dG^bC-u>1)op&iyuDhjXqI$MNf3&7&wfY^}ZVf0?ht7*lVxT94gj ze(l<|idO3LVT6dNaMni7+7=P%VcykBeNnI1M*+YGfT^jeV}204ILIP(*50(veOna8 z&!qJt0E|>Bd!+9_H>ecV|o^=Yfsn(S9yy(0%u99=km2o5xNFqx6XjK7h9X7zW z>FEc2-``foA?8#v^I{*ZNztcG-7q#bwqHuQvy8*QqGaYvWvdl{u-3|90|Y@ZE`;dW zUS?+J+`KG`;#X$w^mGRh3~+SY2+u1&e=u{*%)j_qmR%ShAHNLX$*x3TAprhi=D-+p zFbIN?5?uix1#l%vlAB{=W6PfB?d?W%&ixU`@dW@tp6BlnZ9aJs5vOVTHUOk)`n+>) ziJ4o>9QC+b&bb@ycKgVh?uR|5Am@30>c2E$7|t4FHth$-n5!!*D>L)+^CLx3d{Z`B z??j&G9|1tC)q31oyWB&iu3=881r|d(KuAA)jX}#XM>urLn(C{0OB}4>YQ6$e_j;D zxt_afv)O#a81p;d?$HMT5I37gopX(016XVSjN|xVtyc4tQeQIP-c^$%dAMW|17R2* z(^~(yzL2!mpA2ixyw*ac-UWax%U&&tVlIlJr%TO&+b5eij<++jOw;tRv-Z}#1X!#1 zO0={z&CFwIn(pK-Cn3|GOa^q zj@NE^$O{ZKecx}Cd6bS=W*${a9hXw>lTr@#mus!{l~R`{CMM1cA#5++zonN?TEWqf Q1^@s607*qoM6N<$f?TRlegFUf literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/default-avatar.png b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/default-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9fa88471a83781acf0c00784d5b4bad2ca487b GIT binary patch literal 2864 zcmW-j2UL^E7RNsVNa(R3EDs{E;vy)kf(p{hO4(f=^5CI7P!!!&Tv3qfDgp^z2@rZq zA=E&qp(H_qpaDce&U0gv&KxlE3GC={^K0?*Bfdpn@U|u&5K@?D0DU-N}QX`)LrgH2^{A zEeMK=g`i!q@x&bn+ILhLdBhEZq#^g;Jb(H0X|bpnmtRm+SX44SJ(HJTI5sxEwzl@_ z)xh)T-5Hr#TU%Qdl~r8sI}T@Pcng&CS%> zT1rbxYfUYsth}<8Qb(z)r+`u4(A3miS65$G-_Y3D)X>maN-8fUm6hNKRaNBb>YCyb zd__f7O-(Jaw5*`8xUH?7SV|(5RpjOsRDzR{Yw!djgTWvWOUuhE@r2Tb#wJh+)M{*M z!r_THJfWFNrP1iEt!?$7dQ)>-TU&NcUQTX)3s`Dz@95~r&dtxt$)nL|*zDY_?A-Qt zS_uwMqk~`+6cuB$z}~`~yn@WE90sE!6PuHP%}&qAO3%R7)YiQl8JV1%tgCD2c-F~e zc76Exv8jnVH#axGupkzTOG@zHzI}^{iHVJkjf;yzp-^ZvIzB!=At50#F)=AADLFYg zB_$;_HTB7pCr_U~O-oC|U@+zyKlx9zfymR|iM|nSX=^_hNQ+bv*}O>F)07>3Q)2DEyMeV)gd+ z_VxAk_xHa7P8t|^{rWZV1Dnkr0-gX)8V2IOc?)a-jP(w18W{yHdH?{B%5D4by0mTKOQ1}TrcyUoA5-lw)0jkT(%PT7@ zpFe+IU0nq>USD6ANF*B@8(+SB+1%U&X5QZ3-r3pN-QE5A^()|imifzG2$HLIakTS{ zZ>g;1cShYneyY;rmD| zR)yt|qtlYfbpLSAY+%t=sK3{-q&v8`Nvgr>kx$6!$Qyph@r^1)f?Kxp$QhL9P zR`8nA{$Zju#&>M5lAirvSyu!je%i7qJ9W(-1umC!;e>`#0!Js^PZo96G)cCR>~E$O zu4m^@S4ecw)pAyBA>V^5!p6M}dJ=s!5X%(%JyWb0GXh;3VW|uA{f2jTZtB%6^tx-}ODGdcb-AGb1hdzaQC%zwUgQWyTV-#oUlvO%Iq#<#)s4Igu!V<$T+

*?EPk9lm`;XXd9~ zaIAjOWXqT++!j8H)Gtn)2#Tmw>rePaU4GqV$7JjK`E?Ya zQ26lEa&lcFg?({6H658CjBrHlgiN#1ie)ASuk*)SN@gF`AZ^e-);fbUQdp|6!vZ#$|3s%P@?xZ1_K-N1x3~BnKgytM!yw zTKBfey^nHJzQmo_pg`nL_MJv)H>Gr&>8>Gfc($h2;$f6&)sn!)%>+)MJKd5e?3nl7 zmJRk8XM3qQ&aP4`!^`y1!cD_KuF5c}1$SRdU7u%{gyA8}h6!6$Fo7ZH7f``n||U8_XLb`PWqSwpRo6k(j#;av4MfL8S7@ZREes6uMQsd3@<~VjixS$JSr%Eq}AH270sI zV7Yb=@j6EHgPEDxML)0Lit{IDnue`hd0wmr8f|OgKLg3|C`zbJXD~AE$AhUakp8w= z-zEivX%`1>nx2!=eLd3u%qExP#ky*$`P5Q_P zT@LRHS5)q;6pGnu;oM-*tk8Wkp0ZJHvwypVts=CJVEarEyt5d!;Iq4kzWM>IWR@_it}|tE->hi{|d`Xr8)>q+W*8w>O{qaRaF|_;X3L zbsO2IR`Tar^!o0@Wy`?a4usX>g-3J2QBg+|<^wQ7fyREjQ9gS+f~&~6>m3kah3E*^ zkFW2u-El8ot^|Dp?H=bOO`McjdS6dtzj7qfE~ ZLgvRUj{Gpa175q3%P($@6np=;{{!!q3-15` literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/favicon.ico b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7482a653daf1130d6dea4ba9a92259a8cf15c87a GIT binary patch literal 1150 zcmeH_F-`(e6h+^6Y={&PBZU=}F`+kc5tPKZ13H6^p@Xmhw<9GbE<<}0s3=f47yeED zB<=v-${Wq#=&@RX63=ee@lalIfsEBhb5 zC_QWKxW)+k?i;+XjI@1s?YN#1<@0}YeuZvETAp{6)sE{9@dLMR-X2&UQwsn9 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/loading-bubbles.svg b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/loading-bubbles.svg new file mode 100644 index 0000000..4020b4d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/loading-bubbles.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/mask.png b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..429360d5ce730f002b7413fdb94bcd261339b5ce GIT binary patch literal 756 zcmeAS@N?(olHy`uVBq!ia0vp^0YEIv!NkD8cyyD`Js^j(z$3Dlfq`2Xgc%uT&5-~K zDkOUZ`7$u%&R}3D?qgv1b%ueV3kcwML zKmLP({*A-*E2LeiU=QJ1RAk@^Je8B|IkoT7jCe!ITtr_Iw7T7H-mN|a>_~Iq6)cxmOxaCz}U%#Ui=s2K3N3I^^Y%vgEy)dEq$tzzSg&VCE z-hNH8D(cxBVu|TZ(-bt7gnr7EDXw`FXuQACea6q3EX)??i)Ss{wNCy>i$Lu4wXeJG zt5is|ZI6GmcmLtk$Y+utw&ikeyY?(*od6RG}N|3)b--Fx0`gf zzb;_}x%SBnuxnk_#RT?9>t``*iRooAcc!mZnAfW+aiSt1qKtFX^3=I|_~e*B|L0l2 zpZ(T=$M^C9X3f)^UR!0a4SyS4G4HvFZzGFS$8JvPnb8pYyQ0%A4xY&>OYj9^0NMc%^60)#}<5!Gm85<1XFVdQ&MBb@031k3nE(I) literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/new_logo.png b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/new_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2192bdde5cb354dd4db5f1b7d55de774c3a062 GIT binary patch literal 3557 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/sidebar-5.jpg b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/img/sidebar-5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7471ab8e2fef9a071b93321963660f9fa6960714 GIT binary patch literal 280836 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%0A~`8*jGY*w~u8LamVc4oyy^`HHqR$qaN_oy<_ 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%0DuDx*(!!P26!%nXS^Y2jA>(y?t(=xAKbRL~;;| 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
(rZcrY@enMMxTMbaQQR$2$pm%`uegL-%Gj)9hoS zPR2lIiKA2iOSLGJVb#o<=K-XKQ$lAzLi_U_dAh!TS;7=U!5w~3Xwh_o=OTfOH3l+;`$;Gu&k#Pbsh8mQb~g8hwmxZy<7n4J)$x16L%?-zCMEsmcOe68V78md~TFTd)DNR?j1|G@%jdTezo*{ z%~33I@M;!7URz6jdQM}#&{#&wU-QJdy;3a+P1w>sZY-qI&4{9KrFc#c^a?H~H{2=4 z2lRkJsr`wfJ}e|JHJ)j_F@U(wPA1&OID-1^4iaW4&zF!UhH>eYiYxOG67 zYJsU<`*Q!^U5PF;)d9DLHyIJI74uF#7<>urGVGe%J^Np<+rcw0QQ!aU_}l)nq(P{F zVGv%eG$=?Nb?PrkR*g@s7dqQ@uY}9OFn^W}uLPQtAXq3x``u%VGj%}SAKk2gm8v)p zW~!oPj~CygmUDb@be8~#hTV|r!Rd7UlSW* z>KX1;jDP6Y92g882Szb}*rk<{ivJ|zE^6;51s_h&)okhTl-h#^JV(aH>CoRttzdpP zOk*w_6|FjUA<*}uQ;2_AlW}e4CM%;#{wdIxZ;HH|6&5h`2}7{*gLBW?d;IQ|wwJn_ z9LUP>___dl4(GQ~9Ro$#TaH_fYw_IFcj$MW%RM;iZ+kMYa z3wL3`)WR1vLVPvnsryxSYOYRB!`Hpeg}67bGXwzKT{Um{g>ubu+(`Wpy!qD}=sDz7 z(+W|Uj4&i6MhT-Rv1t}^81;IDhV6HBxYwur|ltQ(WB1&G}s5j`qqqKfR@u-J#55-O^00{8y1JZg@u zub$~(29E;_G*SLqD8~VAVo&zZMo^`d@S{#kt4ChvBDS*7-w$7)Vb%Pyr+U(kTIuPq zF*@QuQhc2E)Boai+5>%mbJA4j7jHu7=SL{dv+#AO6YO~QgiBBe$HcD^|3bs)e~?7> zMegGWf;w;{NM@i(u?R^jcDqYlH9-N8W>*5$tq=EKnSMF(^g}|4PEtx@hnNjGgE?Tl`_EFhJ`c3R1Rhs2GNx_N<>C8CMw|6A^+ zM^=r!L;;Ru2&2lX*T?+=@rSuQuNSzgt?|Z1Nk~b^_D{(N*ZgnoueGFfujh?EpLXFX z3Idu7IJ0nViXIg%QjB%HtYRqYGqwaF+5F>3zCzWfY1`XUovcw=o%Np1{yy;nHeWaz zU!VV7f5-5~K!kIm|E|KHh3WO-9pj_JJgcZw1#$N210#&aP!?c+D{&-?eeC!{Ds*0( zgyno7j4e71@A)(TN$LjebG$0+uAitY=+o4@&*LM>zk(0e?3yTXWloOuTksu8;P6M9I4;t@C9-9RUgZKU zE0U$UA$MKfwx!n^w0|O{z4_Wx_8VQ^gaSLhMt8JrZy|Dy`OKhF&wrrIelk~rW=+4+ z1O$Fr52?OIGk0M{tLrI{Ic=hSPI<$Sme3(MfS)b&v4C@)TnpLj&B7=&T-g|5m8{W2 zNz8W;(#4*9T&DY}@yHLLJtL$pw<3dV{f#asuM@h#FvY$2K4HuHiRw4G({pzWY4WS` zKS2wp$21p#z;y9n3y_!~jPoGwdmN#W+ghuA+??Cwo4WFN^@Pr8e-PJNz40r=3dVVaB7HyuZmiK4{$Q$_Wu$MhUxH9cWj7vH>NmHKe& z@O_w2>3_{F2zm^L;D~J7X5SEImIQyU2=&}=w&nlWl(gKLpkOlo)t^-_eh$U|t;%mk zuB~C;l%hOkpq!~vk7NOWr>(~;YO};NyE1<;7;OwWcvI^mmXGD z=-y9cU!#tg=DQXX^~zDjGnDVOkGf~gKYqAnXt z*;-1&&a13w5hTrigX1ISrcNfJ0Iskab5f1{-0H!&kvAWy;ndcjODRGZ|FTrzoWyyi zo{+6xdN(H~z)I2&Lxl127CBc&o0i9PQM*8|Vg>|7MyD``G2eMQ;G#h{@9igOw`E=& z-v1;CS`*-I=Bv51_^Qu0a)fIniR8k}^;Gh~DNP-~Cgmwn`pJ=J?D`XcR_ga_j*<|#vvfQwwD7Lg*x8N9bKcBJ(WmxmV#fLeB6O0uPQ zA~^A+xo=zl1ePjt;Ih8$x-z-Rc;NC#U3axL1Zi5n@2IP>2%pcD5Tu`X0USDBumdgx z<)sGj#8^`(l&O-`WqmL5VK%5ZF#dexxU_#2D}WM@YI#CagTB`&@@jhb#{Z&#UDp?! zr{9h4mqvGo47x*kwUAdDNCK!LhcIk2kVKlCr$bk_Cq*dT%{TpFP}tB9^F()G+Ct`Wb4rQy7PS)6&|c%jq#wmPcrZhmikFQw4bntww2dfUC^ z8hacp;V8|`&;{iSbZvmVrj#_b?zWe)^$5Fd*!W0%@Xm31Vo%aKcL*tzJBy-8%Ausw zF4AArr-^-cu$w&9y|4Xk_(&9dSzAb$3Wu7mm3C>bjx2*A?|TIb)H&2i_2>kjR`~JM z$`YXZFrS)xF<#m1ygr>!rOM=ZvcsHUim@Y8|1awshp?-hUNd{ePKye(5Np?hA5<=?Y*sB%Vs) zU1RhhhcPqo)ovunyLOLWzB+WCIp}nWiXullz3!en_2k_S9>2VW_e-1`J}33uNJNLn ztB}OzJ`S&5dF!tMbp+ufvNTE)sw=w@-Y|Dn0KM?QNPaEtmOM7`^4Zw<`tOsPFnd{8 z#t;Ap2}QO_XnZK&^=&MznGEht6+IdcCjd?Q-7X1kx{-h3dZvZlx`6U`n@qRCnOC<@ zTt5Nmvb?-q0ixbg_neOC8L!XGBRHCe_1?dk-&$)i(@#pvTxRMd?jN0|nefyw`$6pE z#W?O6IFXau@gwi_eyP73<~IpglrFG|wjfjW9rdSa+F^1v0D3J{{EeE6j~;m^2q}9F zPE->F+|RIW&i(3CxwLRWX6ku-dGLdJOhR}R?Mzo5@VyXZ=T;1&4;{d-!xR`f`$I8k z71Z!15&wQ!VO!yQS{Zn6&HeGF~l2JdOMJ2^ArIk6>HT^9f#aCVFsU0*^(E!`k@#sfa%kcR0_dx;(Z- zn6E;csOqHU?GCi~Zl;cUM;hqb>J2d_YBJ+anmi9W5gV#DLjTiOJ;bBr0`;al`lakz`VfU;rOMi ze`C!yr(>KOV`X1H5NWD1>J>V%yFql)6Gr{Vtc(G-ZXT)CH?8jPiQV^;m8g6Iku!1B ztgvsbII2`zZ#uXJ9O3d%MW&|RucWeG|DxN{6$RqXJ}Ph)_63OKghOzqUIS2>>X&9d zM|T6Kwv-yN3#RszWCewFA&er;1`C=)G7km%+v~A*UX^?wJd+proyDKhJI@39K7-9W z_Kf>^Usj!qBq}V&i4i5IeT;8(fd$#bCI+GTDL;<#MHwkT(p^FwGoZrDOs;}legfL0 zrA+lT>3*vxv%FMSyi)1s0(~ev*rOtlKlXY2`Sn}sbJS3LNsO|Bu~JQ$C*&x^n*kj< zzksb&Z%=|IdNWZVYT1^K_PpbxaU+S;Ph{4!*ntF~ zPpJC(o>XprOFffwoaR6cwIu0C@a&lwj9a#3u6g-uL>?5C6?0x*XnQWJBd)QF#oSQa z=7C!4C^kZ99(jaEJqw;5J1fie&xh_Vmr%#!%-*eybTQl^p+#O8Y)^>}-lrqn7UhWy ze-Xmo5u@MP!Q#@4=x#ZU|6mWyLiHOSn2ZpQxaC*#js+Q7R}W8_)et8|;QjvrZ*zFi zDb78nV=?5#1%O2j_{GX8CedFoPNOAyKr(%C{uzLIP7aBCiEPE(E|s@|IkP@4G-W zexB~pnrb?c`?a{jkasBYY0;g#F~q-1M!&B+!aj}+qB=U{^cqMS(vaA7(_BcjYiG#I!`ZG!8XFuKKa5Sk|ldQS&utch!{|P(m@w(+_s*lzX6weaHKh68g1@8beT2#82d1wl%rn_0AgbO}>wCMg}8iiFez z1SDi4AQEHJ&5%Y?YBIWWun}Xh@ca5)zw7rW*EPn&^Lk$AIp;q2x$ob`W&;7%1##N; zgZq?8SRDWMl~Os-XJT&6#CE7&&8MDR(D<=g|+_q$DmY6IlX}7oPtT8&eJa~foqU> zrE=H=gtx}~nnwbm<{%c2vN#aPVY-)$HhSY1mSP-w3@9`rb`A`~I4piHT+h+&-Px z#ZH-@$z2!TH+)J%!Z@Mx{IEN2be@qHDccqk>-%|zl>2Rx1A59#CCr=~EWWkZ4B?ug zr(ssWSU979HlP{rx|1}gIsPpP95>I79}pC%1{(HyHH_<@k9eG&!mp?TosG~Ml-1u~ z+F4jP^!7Jf%&n{D$QGc9K9Pwen0P0gLfSCVILHnVQ32R#G+gNefbU|$%v)|d;fzI@ zW04HyI3HYL|p6{~6y&=Fm(3m1p#qxdaB+7rD$q_`z zvPt?ZsS2;0sNn%aL8egfZ2uo5P@fZwYo;jzR87#)MZ`(gNf4d&T-w+|P-I}0G}Ukw z;9Nd~ZUIR1UqEJAjSTI zxc|B~K_k?VEO*}3)*$NE0Egb?-~+xje3sq~c6+6x0@u!*Ky>Tm`fx%D=^=PhsZQZc zx?#_83e5iiv=;;m5P#UM(b4ct)_s=wVSR`ky`uiOI6uX>WlirNL&VdUZO2y$O47fZ zTA;;xAO21f2FH4S2!$l6EUaPN;GR%pGH`(rj1tXE{v1E!L&*+X#P_dM79<0hRZ0xC zlxSr*%hjHaAH~>V77)nlu9z;+yA-O*goEOEvl?H-7hx5Ob3ww+{p235V>c%g)y0;5HpAi{MUVqQ$!HSoQ&~Bxz{40gd}vMgpCtKR`g+hM01C_qw=|h zoC~HGm)9lsE&%$4R`p{?S|e*Nz)U+Vk3U7yp-)xpGI-uxs7M3)H(Ep?A78B24fOik zTv?PGp()?0bS`=AzXFtgq&4bz4~^dt?cG&p*JCg2Rc=^TUVAwcQkk#CL`lIn3C7N) z>5nZ=rnxs9Npo7?F-eQ-zU1}&bnd(I!Bs7|;zuCpp|41vHtYt~tN&wVfM$ zrk<)-x1R2P@u|_7?I@GBvpIvd>5;9oUK}YK5oZ9f<(L+yz=ne?_9O|{U~i5(B}qVa z2P&#FMIiF)m+yi78J8VcDCXfx;B$1DZ3k|IrKgR*yXA#ObD2w!ml^H5${idnVOBUe z3)mgF_7<|Q<=!AiEP*Z$lH#p3vCeRI5K+F~Y3SL$dZjLtIW^Bm`!!-10}8HP?^Zop z%L}-fwRLKhYr{rt;!i!vA`;{}%{z?>kh`-Dfs@-|R18NUufB|47;e75w=4c>7WeNy z019}^dxV&ZA(ax9c4n8SBVIpj4S4?W*|dJpqcD(v0A1&YdfdJnDs!?x7dIQ@aU`y- zaBES)e}EKZhxDh0(Q*I^{7b4*l1 zU7>~I6>N!pOsiCP_IC7UK{a|br7M3DziXk_#?Pt;P7ER27$tg_^v&9Cwv4uvQBJ_k zS$I|09|;Ylx5X*C{*)JY0YVl*#zq@c6Gr?sYP+7odI$O_AgZ5Q_N~!=Mh%tp>Q#g* zmD9B|{vU&xBqM;U#r=Tw5_f4I>B?ez?oMFhW@%s9KZe&<^j0)YoKZl-*_hsfp@}?( zIRUKa2z2e*EWpv04^~+(3+Mz|vUi=50RuP?>t0|_TF^&5@cy<`P(Let;j`cklYb14 zB;iA<04Zr9W5kivPS_383i@9^dqU;^SIPPM@GhXG=tXzlWA-BMB8aYSjh;ipoWYSM z(d&k9b3{q8b@gclb(cFCrmdCFC3f9YL9_pXogdks{cU4beQ5VnXDt2q#7E!K4wQwgVX$^nXA z>SEA{Wr@Janv)T=wlUdXE+HrPEl-A@q;`k09^vP?z%FoRsu>}zH6z4jviQYWyD2@d zRog#Cs+SiKpL||BM0$_r(j@j(Ps+tn-kxGjhgk2&u;fR#+qGjVR{+Fq5n^)D^-+O=d*N*Q-_(lfTMT+9LGQ)-7ILiK*^|Sbjvn<%?tW{m zYm6eP-z~Ja8%e4;+M{v_LW30$OzNJs#G5%4kY;ZGFu481qADC8wcPI}lo(K$qHES~ z@Imrx$|7TRLexJ7{x#rQl0-YyT*vAu-9{ZwxJTsD5JRsoYlw5L$23(tAR+{7XFX?* z26?YnL;ef)UZhtAH^QolH?Sl6V~Uz>V*{yn-RrgZFT;Ya3J3Ea06~Oo9pZ~ImobGq zN9QAuuIyDZnt!*C_{}mb8nFR9cgw%0FRcYi3s)+x`GuuAB!8p25M8nt(LWz8v6!kU z*ng8zInnv50hqmvbS!Sam{(BK^t3;ms0F&n&2{RHf3pJQzf4qHVhwJ))_DRu299&! z&F+|EBj~(aO$}_w>j{uLWt@@9UD8T^*{gip1dx!pcB`V?OH>*RI{w15I*Ui&4-=yVtrlWL9O`Hx*&23t9T_T6=MiyVHH}+ zh+9E+UQ?9m6Wtxo7S$M1q-RpMX8{I~X){~^@7v@}@~nGAKMF7QEY(|rT+c3+MX7(q z4*`DXCsx2SCOlORpGO345BC>Mzdgm?j*v0W_=F*i{Vg)iU{qKK(dvP=@j}^HAE+nZ z!ZKNh^o0K`V$Z6VBz^ObLhZch@8spR%|0{=_)sYxi6F9_tQXn=U(|n1aavssMQ!-4 zMI8)S0oa1bys@OZNpX1mkutOgxtl2hcp)Y}KIUfcW&>t^4}(!!Zwn~>hhJ@?L=`p; zxbo}_+}Q?(MIn2<^Qz+?iqbgslE>E6u^K_jk7|r?p+mul;3ioH1DV4A z`#zW9kej}gKJZ??RgE{GfvG&qrL}Cyr5)GlvSl<3bST;q?Z?(Wa?w^YhhQfqiQcV- zQ$k!}Mpdp~e3Po})ABZ$eHDs2wu{rPW>?>6I?iC+`>^=rsA?UhO1)P`W}!p zoRVxe5x=C9{m9D)_a0YzwgdUG;W*OmBddckWn(;1&?@Lj!1v1MyCx@=;REABu0wk= zfX$40A2Ynn7dTW3vX9H(#@N347!n~~Zfwe3pAk%34x>)+%{;l-i5Sl3{n%CQ|NT8~ zW^Bz_f`d6zhguD%Y(?ijeZ2;z9lHJ1ALUGrE3MQ{PfiN&1Iua2*N$m%OPDPNtQ8tH zkGm`GrW4yx)b?hgFs*PXqWe?K6ZJU(3+Xqu)BW zLi>}*B8^C#=yG%uOWx#fZd+ko;BT_9cupcj zhfp4KG5hI+^PR$2W{x|O`!e8mpyAxDnl+jRcI6gFSd}4<{=9l;+B*Fz<7fhTA6Sqg z*m)MzeY#sje_58#qfj>ua@`fuI*lDg1BtDa3x`nKPbbm4E z;-;YRE4TQVr6?)CXM@f8S;K$|$pHvx=RxG-{BQ+AQYwLSac7{FgJ8^C)84v=hb}#; zaKx_obuJ{=FMo?8=h}5=J=xWOsw(BQR%py6+vn50gI1lMWc-DImHsiDr4DP8r3g*d zjkUu8FtaS}HG3dcFIG_{64Annc#o41eJPkCz&zo-f_<+1*cQ z`b!j_pE3YyKhRIvbF`1m|6z`p5(0)_L!^Pn0W+F^C&&gqx|V^V$)JmXa!*fveu}wG zD!1_od;r@&Pk^+-E(UAdAHq9417M{m(1V;hx(D0Q=Hp{^($ zp%=ka@vctTvwkehtN9!30CLzXo*PupU#7&>2tAd;be&A@3~E zPS5q*3$ExqsSsck&@Jw?EYi;@u^?OiV^}>9O&ii@pGD?Fs)BkFl}J5gUth;1X_jgc z!`cj!XLgyA(tnE`S1Yb7q(V3iEJCfrh3Mt=n%aEh#f zGRuZ>{dA@Wi}0zlU8mmfso;X|#XsEYDHhdiD-WI*UieGjyxghiqZ+gxcVfJ}PQA*v zgzg%?`e-SU_w?YGs+!I!t}{RxpYozxm(^-uC4k`wo!s%Uj$OgrQ+sQvg_s78X1 z2dDNh$v`V?P@DW!(l6vWgYf>tw^`KbYFY_QB{*Hk*L&I1(cBI^clGB)e!7-mtGQ=A zg3J=yv%^I(3%(Z~3IL3$ORt$D{3WtI?H|7tPQP!FQ1KPVI;y?Eu#$3Vt-5QKJZ0w1 zX)&Gv8wm0)Ix4-FB>OJK{Khv*U6`N(#Tzzpx`#Jh?rOz6a4h^AZK(R|x-2f=b2c47 zWz0E@N1j_n;vS3E_k>cG=}c1;1u`JMjwAPU)HQk`e|S_b9q8+6Z|5v?c4jWXgU>|f zoUSiW9`AbrqK<=MQ=YaK_lRj+{erWYa+(p-pB&da<3SO_euUvR1S3_I98y5e0KoVX zsh-$dN~)G`3$-yG^>vr6hSRNnw-+Ejc}ljqzBQg~JwsMos(Vvo_UInw?`fIBU0S&O0B-*3!opU^(ynU z@hF$k3R)0#YuGx2e+*I>)?-TSSa!zg5zPorx-wQpF(q?P1Z2Z$m#s=+v$iJSTG51@ z<8k1vS^n@0vLjT8rpouc%l4j~lsW-Q-MB;aboo4}W^}wGX&C6LwjFeY^MowLIOaT-a$88b?_E>N&!hgJk%>F6uTYS zC9MMAyi)?{?mz>e`=-vjaQiV^NE~hqKCTU?U7t8C>Qs}i1|pfP`sFh4#I_YE+Bvt` zaq0WprX{1wztdkH!r=Hkbbbwnt+o_c$2#FlnTLZhzR%(+t97PGw`K#1IFa@PyeHlF zd9lWV`xvr@h}x|NX7iAt=4f(w{c`IEhx#ZcV zi}p0%HM3fCzl$?puLKLV1WGyyr<1}o5p+=D@rLUijhDxE=`7+xm&5ob zKAk1#0k@%zJmvN@kbbGo5k4uMuBPW-mg$p|zt4h64CYdHyd<7Gioc5;Idts0jx!Ir zi_EsA2daW`+{?fN>X8<(hjPbNWd8ivULzLpLM(P8)!+@bORaws4t7KM*vjHRLFroTsqsy$QQq!9~*3Zjuwq;179mFCn z?P$6G#22~rartoDJ^{>%e+8fbx`8>#K)Vp2oA6gL`&L_Ny(o0o`%Am3hwj|}{&)-Pp74X{piuD5yRP@;dN?81bD*JGdB)MfDEwXQSxoDWgz z#&9j2A6@jG(^nc|BqUt~A#9JgG4T*qY7naDTmSd+$bgU=(E>)JAw_Xh!?OoMenDc& z=Zen(#bgW6P-}5DA)}>ZisA>b!Wasth>q;;GSnADn6NNdk+AWPEwAH&5B zPKmYyW-uWN)9&|!y{&oz00j6no6h811jLH!%ZY$Q7{&K+0Xszadof(8gx|MD7S3ru z1x(=l-8_}~zr6hvfQ~0igV^6Z*q+R{ zt_;I(XF1Qr$sAZlf97$v>{)*LfT_th8E?xQ(cr^(YWjQ-@XLbmL1L72$hGH(^9F-g zYU%DQr=i%AaNUnMs`@^qU!1L61%26o&snjr`u}k?mljPsD4x zIl23`ZAw&%RKTMJ_{}~FK$&@Sq9y6dA3A}q63ajfl&HL95s|4ropixo!`)Th(_NOX z!H8$`UAZhMt}+IarETQ}-1>NuSXXoY>|O4C1(o>FUAnkyYV>T~_WfOXJL(siZ4>$H zrxtC>NAyqXFS=x&4c|MMi>nX@gZ1x>hk`B?=_g-^C{fF5Fvf(U(EH|j$@Gd7d_JT(0lXo^W?ac9rmKBQ%@Ce znxb6XCW=VSSV_qLxx!QWG=Xj1V(D326;Iob50WJ0l$DmX5XQj!r2`0pc3yp>Us?@tO)OPGDjOg=yHd*uIgESw@kRSAKzM!>mh+l^M zG{}?EC(E{Mf9->yHPDkh+RhxCz6*AcXeNA57Acm8GRf(#i2vXb&W+?M{-S3iNTFN_ zzcP+-2gj>IqF&h~?_LTiw|4e?@zkIxg7Lx3M~N-a^rPhqi70aF1G4i%Wi9;@K~0|h z#7KW`#`9$5)qY^bbJmdC2w!XZja)Eb=ezT{6;$U8*rRl2`-&7vdNFTI#?6bf=HIr- zNC0~Igt(LS1sBk-5$(NA3ZNz#h%=^0k{f7fh)#9Q^kEw zW72<^fqeHmo-RmcXDR=}FN|->U{LQ-&r!TDs}dVE3vf2r(>V<||VZ2T;1$n&YzYNX~dq zROwUm+}?0EOk88p2ZdYe{oR*X8f#4_Z?{=vHyB0vfj;1$CCw_x7SUlRAR~JdG(pWU z%~!g3&@wmo1+vjfkLiWo%(ZLkmK>P=AZfjCTwHSR0c9u+OD=s(k?iqEY{27wp0Dj* zYEkjnHFy3VGd)juIG;i4s=@;T%KaGHe;7Bf`dV~1h?RlFx>UMnX(wRLo6(sr~*a@vJOGh z5%6W@WBSoy|P=Xf0-Sqa*k{G#}JzbS%`kA z9|*1<-c!@}s|dykp2Dq!n&t#4=^J3om__E7=ouI>NJhC=NR(&6YOAPyI6;%2j9rw7 zc-^6jDz7M=9m?}gd;dh+xjn1Vy|P^eW^2EB*Vq-2wQjk3 zG*9nd+(DJCAIda}FRa`O7B@{>`x_d^6rhUhUkhhh#=BC~tjC*8en?Mymly3&AlhNgm*c)2ev3LV5R1D?{k5$|~*OemurE5TS=E3S&g> zj-af9XfPhnFPY)D&QknvK!}5VMBV9!u;1c-h^cY5D0s37^uCBL&Rp2Di>cge9ysio zD(r?Y*unWNW$9k|DVhLk|Lzr)jlhk!TlCaF?&f`R+KpKp7MW`9Z@4D5;OxsOTg>Bp zsS5qrL1Gz>vs#n~c1`mhK>hVoG)fI6NF*PRy-Oq)GZN92KyDH{@>|`0S@EPf+0lz{ zMDcj~)C&zTHs6(Z0b_A2$xCRVa;Yb8;9)y|Tu-gyW6%nj7I|UaeQ2p#%HXOIGYiuP zXkZJxlpBD_a={bT!#LLtAaIY1*z^A zAdOS%&N!QLIyej_jl@lv#Ses_NZj*5=#AGF#r=;mD8u{Om>n_4DpDN55kBrP4|Jr; zk4ft>12j}K0Ij`X2NY{=`#~zsv4HT53-c7_2Y`A_+%DKN9xg|!C%V$!1EtA*eZRl~ zD>8`w389+bDgYpIuqQ{s`0zclXhv)X=s@-{Tz7-^Nq&#qg-npZ89*P5&Ds8`tYx8` zf&T75kafR-9c~qaT}<;yPUM;jpYt{7gOq0deb{dlW_{^@(~{6f%K-f1Fi%gtDS23c zpkLZXJvx4iUG|=kKmvOozWL_?MSr8LwUg`xcX-CRwS}C=-D#n+pm0h>&a7)Ujh9#kX+Gf$0vy}V7VSHV7m1PrV!}YTr zTmK!D>s4xo>|{UvQqLyxQd!wcNR6ERJps)n1hKro{Z!U=>Y2`EDE|xX36nRf<5*tU zrQ|6SM$_Q`ivHA4tUb%aqoC;)f+d(Qp(dZchtKM%dAMz6iL{~O?BSiK@aV-`HW>r- ztposK)jS#uj_kHdv6Ia_C-aZN_X7Cz=+_pmYOZ(6v)|UNV}9v8w@@CoRl?A3pteHN zfJQn&teVwz8j3Dq-bjTjprOowQHgqGUlGKRQ=_?G?EKQF8^8U|SpM32&||xBbV+mA z1-~INJd`htYt=X@|NDGdqZ(>{`b8dc8(;P3>MvyViCsUiu`^WTd_JT;?wabeMXUsCsNd`?^Rh?39q|Ar+C{|0!wtugA z4j^^Q5n2zl#$)ZFomj>4$?Ugb$}jwWAN37`y_ovtiA8dKRP!4)xO@-ySCQtabsk7}T?>kzvo2_w_X`}g| z%xxsW^szVDVQj&t)^Zt4;5|Xuv;w0>Tl2d;2pDw3n=F>`p&Lng=%6)YW9Nz_Nvu+4 zZM>-xr7}WvAUvpU^)1j#js7wG#@t*BT`B?Z!HO6|B820n+Ge|)q<#VrajB)D6@#3Z`i*SBXdM2A8k5(fJQtSdu!f773?+ zf1Q@xO?6M*Ik2(bZSPjfRa<~3h8%RXKJnK`3FHTISI<>XWT6E( ziqDK}VuGJ?>X}2$gV=I^!JA$+lug8_AEPjW)4L5-!%%0`G6DQi?|=B&VH!LDxNa&HH&NDv!D&cwubS&YxbV6(LiqSXW;`a|I&qMq4Z}ox1!!YQUzG~ zsjpe*J@M;0{NsQ8YW96Kk5V7?92S3CG55WzW19@81r$7)x@8fI4aA`ZY?Juh`rMUm|&Yg@k3`Xxw<(0Ndz zb_LO%vBQq5iP)XZ7v8__1%4xXYGIaC%rj(Zr7_lZ`m<(qayD4^{(a3iXQ-va$(bvI z{&cyf0Tk#M5jsk~NdP;L7l~($2zxP-x5tknOa=l;#E*rs=RW}50R|2|Wd`0OfjZZ0 zzB`|@xKf|#mXw4Zp+^8-8K$j8bkXWvfN>ICv+l(r<`OaAuJNE`E~QryLAw5fpZ$Lw zof)z(kovF@3!6`$;4rcB%)u_1nzL8=R?>0m)M=yts?Hpio6(sxi1eOL*zGa809lg_ zAe#M0X0iRaUL!ET|8HUhGdhNUxI$aZ;>3VUYN=j?TuUR zAg$=SguNvAbpb!$WdG8oeq6yl@+ZHr2ZOm5Xx4&(4VZLH1D1m&gNmpif-|-o zbG^;Vcyzj#a8z}L?`fl2zT}11`?(h$@XWxYTj8`Qj1!9iDT`d^T1cI2d~z1ATDX4B z_Wl`_?c>jh`7`TZ6?QQ-J$OcEqRvwJheZr?EIyoh;Rvd6>*8CBRQAPHjUnB(;TO4O z9x^Ew!awD!Ess&78Z8cU8Op17bybHWJl7~xj9d@K4V-Wq(*@@Bz;&YnNb%c!JOwWq zHs5>=Wneh_*Xm0+3)!)h{s+Tzh`zWHLUG8uDf^^jrS`)E*W`wcl1n{2$^wQi;f6$x zX+yvG^elI#?)=omi9@yzM}a^rb%OQ5oh+e{1SHpuSryZ=Q?59rv-LB-I|J1|1MZ13 z_9?V+E>#1oZ}u7yKvHxg-#B|NcN(+ZBnw{1!_?5Tzjb}53X+4QQx`D*t?@V|8TOah z6NXljdv)%rezdOGj5`VK?@odGR_V`cYQAuY2>4OcNvV^0bzGXI_-!&}cNTB^Cy(jg zO3eI3E9#_5KR)vSyxqI4aH5I5Ho30QwI#8t8*$$M-Ol`jrunaB5tb8Ak-j-EYeZB* zFX6vfy+6^XY(tM#o!2ge?Vxe_ploll)j>Q(Dm-Wc>@uH_B^ocEeqm298`e#!5)!j| z^lLFKmNW!CHX}LE8d^d0@vO&S0%DuJyu^`3G1Kp|)xBIlh8v9CY#qRZEksjNhY z^L%ijt5I zG0=d(na9cN!QH+eFD|3PeZK}<8iG52qSL3}gj2%5V+uKvhiVq!)xfZQ{35oe|D;Aw zzWPtN)(tRGwt~+liJ`yeBcg3rZqHr?!mWMxUbha^qqzyaPe}^*(lXKNzr5Q7{sTBH z&cV*+>v^h0EWU#RDU2%!hv^1YA>uGK;nHO@?iq~C;taxZi}1#cwo+DOljP|OEof2= z@a&C)4@iD-6wA2TaIMAC7cDgs3JjeMXOEMwNjB#;BSKFkEPm1lvjx~fPh&0fV`Job zKS73p0`gt(enS3T8&MwVRInS|5k!{2yoYHsyUqg)ICa3o_ zvu}4>pazY~n`^Pa)v*Fo0RRba*o93bE7)B*AW`8O7t!-`OMR3!mx!s53ux~-=N{6Q z9HQ~G#)TOBq?S14_sn@#N?uf9KX{ZnW7b<_5Q_m zfRlW^x_{7{q(c@H$>sGF;fpYx)Lr7)-y7VPe~ZDn4G6pb;P+RUGBvan!|h`6`S84c zQ8JI!e5GZ~679n2_97Y~Ne%en{;_6o=+o&lobz!?b9J)t`w#El=v|zC!_(yl@QZso zX3ds*5Pa<<-$5l3V5}wbtLeq{6eaaT8}>`2LI3%Rpy*~GfoCyX`0Jm1yR`^fEIBI2 z()!rs-5B?<7JJN4nB_V!-jCp{p)P6p5bwL!lt1A+C5NlL87sIrN=?O| zBAQ1VThI|E4HSdLQzA;UF16e>m0Ezm4m=8fWn_sZ&r32H4@|%8XzZ0IRGqd3(WADZb9h zJ;_k#vOnntA8#H&24RXTH*xnhSVP}wMvzk}GE{4_<;TC|jP^RK$-u8=EDBi=?b4o0 zvd(W-eE1{8Ou8G~9sXobp!atr?sOmSF8}ZJJFY8B+3G!94m4soTa4DO1%%oifOa8iY6^9CZ>k)~|2-?2ZC87uYnD_}8rlCG2z+db@Lu~!pXW$#0x)hV}@(A zpU-}NRH|h=J6#yU^Td}+e7s9fc-4~lj;m=Y<&;BH~@V4h|Zk(o>dJD^HRwgpI%sfV%6j>LZqi_)E!JeTSwo9(`D z$$GR4v-c=;H5#7DxwF7?RqO_X9Mbm0ZaHBts1pTT^y}aA)Ii!cA(ev7{A+Klu$_rRjkQR|{?7gs+&ke+=@k`)LyxpwX54VP%IF z8887lyr+fm5-I^+1zjPMGr1bPiNk_&(!xN*cUkMSm}R=j7{)n~$EAE-C|18cY(`bd#r-#6jGp{Z|$XI&SJY5txi92ck%O8L)-{2B` z#8zXu^Uriy5PuzC)#b>ylP%zm+-osfv?K+-@RNC>l9got{0iP2kQMq|OZ6PHqkRCr z&umf-MeqM$0xbHx(kmAZjdAed_mHC4W-iA9^0H~>Eshz5nKCDs?#b|j5vyh!eps&$ z0GNMG28Qz!gW;Vt59~vtOWy7AekNMUGuL9^V-BgJiM)Fx0cbyaofmpF|K5=HZhbz_ zC8MjDE>6kX!Xki5-X}e>6_BVephS9TQ+tY+-uakP3pPKWFJg&ap-;CJL`mxjc@10HEYr=P40 z8?i<60dft88r+0U`?`0U0uEcYck>h)AF-h7O%x_NOE1f;E1&;-MB-6!Sex?i#pzDi zgdz0j$f*IEC<3J8wargYMP-ph61-mxDW5UFYxRN$KiVYz@;2A?4ud8bH;qk{P0Pac z)1F)DRKSEZa9vCc@pU7aYC`-Cz8H<#v6vZG|7u9@UUgAi$oa3Y<4i8O%QaYHVW)8@ zk%lUU*lsjRe}2gwbTfON~2#*j=g2biP2>W?+{m3iymO zF}0%&{D3E^;WFE$XW>r>#xZ;yANwMpg=Mv}xb_C9j{8({>~@SPYiM}ALR{C7f<|_F z78G}U0x{G83~eR(1*F}tw>AdVv<6}=TC+(9n5$Ig7;6H4q9;0_3CylhpzV&&k2VN< z|6n4GpJm~4YIVx_@I8{Tgr$(c_BNpUdv?58h{!9Ted03uimC$s@?%!N-oTmXym7I2 zBSW8B=_&v;8*pLc?-oXDeC$(Gl|D94xlb*f{k^TE(oXFY-rJ54s8)t*-4XNKuZz%- zDsMaq&7Z}%{RA%}VC?H9J>hbjlrHoq1w$D0g7b%764wzN&jre+@KEnKwn6IHsIlPo z*89Y>C$g=YUZL18Z}dkYa~bqc!=`mzAOg^4*V9(aD>3xdTys&!`VzL>`RvAseePpO z@)fkkKL$u>vtZ3GxC-7b^?FG<&eLhspHyErb~`StZ+7yIXKJ9|(8`?+AGy@HUDTbi zNWVWkMp8JL86fpoDDhK=SGRt>KYYrCrpI#~cxLYrw14`*SCRB62vETOGHgCu99*=d zg^jPK1YihbcGJ@lt&>h!!XNK4)sE^Pw9PPRl&(rZbp%-^xf}K?fPo7uMPqrwM}uz$ z1jPX`LJb%l+VUwpW^1xokL{h`naoM&kZ^QguMry+k)We%LWS0Je}x6k;Np&7;Y|iB0Xf3rZ*M>-|KwmHsTu^cZ5HI+jZCc6Tzty*<8`Xa z;-<8S9S7*=`!c zj@FRV^%l}vv^v4&3veZ2+(s*Pq*x<;rcP83%j0`AIdW#FA^}{dk8JTFKzi2aYFOMT zIjXn{VjBhC--(I)^U7H~WgQ}yh-d?585KN0=eo6RdREOezmKxDL_TPBh3J1tR4JOd zO^7Hd$N$Qnt~skyRrloR7NT02FCLc0+@G4_Ud*`{Bw|^|xEc%de`c@4&gTfx|0evL z2K$7#3IBAk;n5Jcs&L_(ApcT{alnmd#Y=f{o{{d~GnHf5tfIp)c3V|Zl? z>XuuzTFgf2$z(;xg!iJ8$}Q#8)gke5-(BV6e8N!&`~DArJi=7ty*Q2f#}Hsly=X~n zpMX2lx=o7(SL&|7^QQhW)VrIAA9bh7*Vb;8G$i`WjNXm(zYqxccG@5PJmTN|MuMc= zGqap2i%&SP5BjAWJ|BC{DRKJRBS5!=od!k5cVM+zfyK=~1g1}>rhi#AW^_*LvOCTS z`z_y9y9pjmQ`57l3Jb5y2Vy{t8O*vh=@+o#AlJb!KuOF?-s}*M4BorhE?KWqbmJw(@zS4_ zeq8pudbvVFVi6i4XOeBvFBzT#nqxYl#tW53p)5@&N_7lt^ysBT#evt?tr9r?c#~^R zK`?snDa8#;FajmmMkOS=hGPRQ_YHYE6Z!ObxrXzseE&xh-Y+GiJe$qDMd-4#VP6s< z2CxBDu2bN(SE9?=;US6!gDQW5lE$=+0hftHz&G`@zmwfq7+R?@9qSWX%(byv?fn5& zGz~d@Vl2vTdY9dbB7NZch{A5*y$qU;ZJ?GBu_+Y&eWFH?~{M7ZStFxl-xKxb037Z1sW31!Hgc)Ahqx}UbYI>SQ~B8;LT`2 zSwM{Y9lC&40lQK84WDY27Bi&E&%5bgbku5IvjW&5C&f<0RMni)V}=OGj1YQ&2k!a0 zgpnZYI2+&7Q0j74jq?It3&H-i$8)I>hO#<=%$OCku9k+?+6CBpjz>T3%B~BoV2eCr z6P4n1r4dcp&Tnztq~T~vap=;Cx_0`qv^(pXrcV&tP?Pala{Kn9DM?PftI1z_x2A23 zE6Uu$*?#C^wj4<(UG5vXEaObo4$mCN)~_yWmxOj@S`-_iY)Cyj04d~rCb6g;8)HPY z1}JeIx(VkXDxFF`XL3`b)S4m)#sXTfWZ2+*t<@V~lymyxbVq1o3w>~Z^O)&nLwq^R z>^MfiJQ?yXkj^lkZhYiR90_^X3edyff!%o1Gbwg%EIx5RQ7wPL%IdUS{ga%77{Y$O z>Xv$CoVVc@px#xhq~cKG9}5ZxuZ>n61pYymXVtv7szva}R_feJ3wZIdjqm`yUIg?n zJsI0E2$h+LB}RC?J=7w^hXp{ggvye~eDy z+H{5MlV@6#Y&8iX=`KduB z1OD&#c9N9-vl!p!@qw=CHnaT@4F7R3MthFV2ky|!xeJ&Y+RyMy^2t4`T`-$i-?sgN z@-kKO59eq}nD55K=5mclRwLP_<{=8L#jl-TT|2Ni z>)u(VXnpy}9LE-p?OqGaTC^kAF&*zs*LC1BKET}pWOhzctk%E$`Sb7{C8mznVYWyOcV7pR7gPqL9MK{}_tMmEC+{O)acrq-TL2X{sIea5&hYsPYy zvqD$lC`{xnh1%F`uVqa2&=e0IB3}BPC$rpb%|Iy&AptB$inMy zrPaZdhq!0YZk2Ssc%8y8Sd7@#cE2>5r#j*#Yp_>4T|{@~7dH)fp*Qt?lro>Z38@4F zN&KP$?Ps+?n7xL71o!=)4L`@^S270el+#5S*Kb^Nc{yNxBn7!cH9_EE3KPQgqw%7H z*AP?KFU{)>)wH6hmEVe}mN8c!jR&B~)IednC48xyuje=g{8ds9LG@^ z>PkpeSz*lkg5yt^I|7Iu$L}X_K6NS4?}e=3y^=kQM+@t=4ef`zjzF2AP(*`Xj~1U< zaX#rWS>cB}kT$D@gkGCd-uvd0d3iYU)T)F&5-NvCXq-vzEhq9$&*Ad{ zp3hxrX#rs1!oF#tB3jpHjk%-{=nVup4$a?Z`}wa?uG1!kTS7S3zNjLPh%jH(;@{#m zpws>Tm4+GR-g#qiN1Cbo7oegt?-!gw`5-HX5m;MVUUj^k+dl@sKHp5f;!f6JP?X!S zBfNy(8Co60vi7VGl^-CWsSiw6yx3!!1!(Ug2>IlwMAPLjKo*kD!L*$y{Ifp(7$86i zDK|TC+IzCm#B$Y$&LXYkm{L611v{}}BkezL zH_ERHgxJD`{hn8tr|Gr(8D#2-keYzKTzd`vuT^Gnk%a@!wl#Tg+kvk+VsuJxzf$Qq z`Ax6-S#sdE1FAUu+Sn0f`fy>ET8KCWX%=YUf%S|+^+-K#qeG~oTs4jh9`QcV8#X-Q4+}e%OTXD} zz?>8{I-PIO>@XOjRx~=D1O9N-P$rF2oJlBnSMVJ1qbOXJ98(f3>#6T4f=5j*nj7$F zrKp5}L#}gagv9{_nnzj(t#Y%2{J!-4xockW>3=W4^$(CtHC`an#pXrS%nDLb{D*2Vs>R|P9kR9Qblw4zx!o*(PzvVtg`5X zL8&%W=RbjZ!X8+CL`_A#;8*OAjYj!odN23n4n~QTQn5}eEazPCN|Zu(84BuHTyK8z zF=9LNVoITdhO~4qNsbBA+M(BC8?*KsUaQ?u3<08}Z580L2eor2UN*cbcD+59QU4_4 z{s_c`Xj|$pjGX}21jZ}OcP56US+U&Hfd92UnKmBTlgEb*?PFKL^IV5h&l-G~Gfu2l zf|a+h-Q%Wkce-l>{ZB5d9eRpwapul6?Dz3!suOq-!WCT9ZYn=`;Fv{;Uyj;AQEmjE zdxN@}z7eql@7G2r1tdy5%_SN3B4z00^2=Y0r}{8!|EmP8K$hZVA&{vUdPf;iZ&z5DpB*Ej`F;}S@&raSp9K$7 z54m<6E|C+t(2-^xFv*c=hmnQA^q$|%*N#-#ZtY#Fs%pkg?U53DOWG=0vnXn&s;XwH#3nUEmDG$;d(}>i2pRpI z_vic1?_bH|oH*ya&g*(!*K>rPolGJWQi}C4!#h#;;s4l(H58Z%Bd^APSJ~pEJsd`e zY^bp>q;kyLY!MXd#I48R>0UnKPw%}hwqzA}m-##3-;IQQ@HSi5BK6mEjnFVZYPl6x$q`n_^V;-Gv7&|NQ9M6esTR z;QYUHEMspEE+LPJ5NGT?6QF8)bPQzUUc68&nAlqo&Qn=?ww}oRC}mapdxTh$K4V*P2PYgepL+nvIC{$Gr%rFS#^2H%4Jdq-bPY@)(e6hI zH(x3g9r@f?sBG=CEGs5ILj%UdC-FT9VIY%nNv6##toXq9lWfBv=++L~ect--I)_jKkpyr8$1nXYLX3CDR|rUxD9YpiSHc)4kt}f>eTxi3b*E>GmGLUaI~n zdvW3mg#PG%4<&a%9~wB`I^^78(b7P0^^10q&AhNUF#5gv=hXP-kEuuh_X{jOcFo*t zzT;{m(8z7IPXmwt`kz>aoUuJY1};*9w%N1@U_)rK90M{njX>3v=4*s-5Zc_JY~?_uSobsi`Lkn0C$=tK6ue~l6ls@0S#qPw z{$)a7j^W#!iyPPJKz-raM_&Fp{Os{|gitO(;;?1AxyAneci1|(%71Y+Vmy5p$Uu8l zvWpvLJfo_Swa3+v9ZC%CK$Kjx^5IdA%xasW!`!U~JPF`v{W6YLql#{Plc#YZmuawq zrV%`W%k?jl^a=F8#&iy@@2d1!3Yf@c2{4;lEgBBcbO{L_K;4M#{L7>o3i=x7M6cIo z!tEA>h~dT(@IWQ_!C)0J1Led{kDD-_XO>VeSD=8s?z>s+43Ofrg`{6D10biV>=f7s z{W=euXdwwy2t{StR06%_G_Pyngb_cO_g<~E%AwYw+lL_?TNOgC;Ki*E2Hh~1i#xHf z_}TyrS9i(f+uO6676}X+hpLzj%Rnt&jvorPg4Y@U3j&QoD_41Y-9n7=13rCse+}6Q z_RbH$LpGpKksZRag7PymT_@C!(+B@kj-WH#YQ27>Q3#VLqCty(BDsZlf-{1(&mZpH z^j}M_zlx?nSAPC6IvxXPPM|>$8giERh$0T)Iw>gSCkIIMad3Det>U&vd>{y+h09YvV)L=D z{Cr533CoomGw4C+aQ*xEZKK2L!aEc%N0k2>=0UZ5(=Dl8%k+vzp~75G6U@9 zr)ld!{ilQtNg5y0IDKyk{_0^ha>?=*V3>+InQIq){{vxu0%=R%dQsv#U$(sLnk7*} z&8g|ZF&7>kuG6m8bJQWG8E5UIXL2SPytSYWsBXui!0(mh;EUy#9MblvKt|yUXssnG zQCk+A*lM?QktV(3V(H+YbTVf)-|%pE100KMAjHKFKfr zUt~D?6SK*-B);B%z8II{U|yg9Y@)wxLXO#BUe5e)TV_+u^#1wx#wi37#Y$1Dgfhl- zMFgYxc$L^1gU>eyE8w^}nf8quNp;c<;Mm}K%q|)hN(6u3|D$l*QDg!m;_(D|+s9@X zF=+u8t>DXI(m89T0(-2|_Re8%{BRzFj`Uhz@zBR?l-(SqVe#f2t)^5y?~O&-d$z>6 zn#Fm6jZ;k)m9xdO*|~!(-$UMX_Ce?+=PtP}K+-xED_*Eh=%WD@jH^Q=WE99GXK9ZS z(k+uH7M9@`xZ1n^tXyx|E2&Xq#~O7dC|Yx7>2cHL+zRqV49m!jh<1(md0f4M-Dv*1 zS&fzrBn7#(&jR_@mLlE(;;8n>G)#r-W*&#qu3|gWJyC)ZY1yJynPA2bnKkfb^i<}* z_K}1sDA8C}E)p%`eVkNTPuwu8227u=gQ~SRi>);a<8^r}H(jLA%79De&SHNNg&OFe z^lG%4WAp|@U=espkRvX9@GY6~4{m(B;+Jy>$ZSr}l5dYVjYL7q!&xxSqn~aZ-B<}Q z4o8#*)cdt&D1P$lzd^*T8gNQEZ_d;q&EqhPVtu0u6k|H2bipUzFY3`RVuYgs?GL@Q z)zsx9&1HgD|3Hp?Wa;MCa75wwk0@T?F(t?MLNCuuRZj{%d955@k=*rR#}esnCv}7V zG3s9f5>%e?5~J{OP9+d2zZsLq;L3*r@4K6Y$z_|+8E{Q~-Tn?6z5e;FZQX}>dO?;l zy^ta41I_NM$FJXfRKJa_LDT{Lo`x&Hy5s?EQ+NV=!_rQXr;ieOV@ z^aBn0nu6ROQmN6iz;A$3Epgls7%w^NxSfcr|7B`h)DZ&)Y{HO)XM#up??>~}iDk$` zamY4YKj-pt?_4Ib_emA{HRi%HL)R53PO3S&+i$u_+?j+{MLe+|HW(a|3l==kO{8aP zJE*pl!KNeoMr_*i_xTNfWNqXlR1OfumCCuNwE13{Nu-ky289#s+?#DN%Fw1Jki?Ph z!I|zE{_Nj{3B01x>bYfdX>=1r9eDDO6@;vP?rHAiWJ9*Eroui7Q zf%_v@g3UY9Q5=~p-OjF%bjW=vjQpP7I=T=DyrBuhGoR(f8Npi&u~AS5s>& z*gSrpY9*I%xyyYyyee_FC=)iKQPTA2(cs>Oou-UZ*gdPmSr8D6bKSF7f4D*Am#1nY zF{G@QO&NK5rCgz`VG!XVCcW#dX?`=_AG8cv9c_0uq)GLcD*1skO%#459lfyhQ#!Cr zlohCcf1Vi?F+SXS`&co0Bp_@Fz@KMmvg!NxXN7$JGKG9Av$=mZGYQ2U#?o#TtP_|I zDe^M)I=xxHmH6WF(5GrxJ5jPzOWoekFE8`o6Ysrl&W(s zU**pti5t4RaHJ{qL-p5zl?IPk{BdN<(dQFUr?PXh$!%fPUC!ENpdBkh_k&~aUupPL zMWk(CiaaWJn({hNr7zyzuJowI;5>@<{cj74$FOB9O3~|;4r_<7sLL_4Sycv1!$Al*{y=sO^uS|CzpSO4w)l}WJF!&+6 zmweE?rgd#pHTqvMq?xo-MGL2y6-4(7aV>KZ%NiCUq@&6I(K^k{K-$PKWrdngDm;o9 z=stA~Oj!FM2pK{N zs|SBI!6hnSl4>Te@J&qu+)xU^kf@!!JP}hKb!*aP$l&Bqw5RY5pwNc|88XjHMsnBNky2ojkcaqJ>;L77M)lY%~I^iK^vNX}Z zfnMHv+4}tcQKJxus0lo|=dFnvCNuYNBhoZP%FH z3*XVZ@$FHEDQBn>*ROxJ9B@6z$vxcs*}4`jJa?Ff#jsECC3>OJ`})dPPnWOdiyAOr zXiuTP%{HJ&lGeKzl4F&ODOmCB8&{L14t@Iz3nD{>x!uD3^V)TVA zs_(H?x`0}A;e)I}mo)pDx#Bf-nHQVhB=ya@8s$HoC}p>n9e`ui-g2lM`!JwXs>!A* zJCIa$m?I_@RX=NP>#1aPjXo3U?}(G^nk>aS2|ryS*_}#u^p~cE%<#(o`llalx?g3d zF(-4c=NV1RZ=>Lo)#vO*mR$R^`4mk;izAH#JNoRn-_8H(i-JK;(~}7i{L7UZ6y3&B zglgseNwgPg^XyojB8jDO)z6cwe9X2i#$87a2f6?I#_xR9NUI;qg^rcxVzSP&-n`^hDzejolZA`>ZzHD<(#m@ey z@@%V7T)R~L?zD-Y{&JsqRWu7#fHACjyu(TL_7ZGw^A~Oaxi_XLC!aAm!xnz0oOvBD zsd5nh$-kjW?dEoqNVWqO|C7LBmKap*v7@n!HiFVxQ-2v2bz7@YfKBZ@*QhLnTt(^v zwN6(yosyu9qxH_{E->ZR7!~WiCvs_l-3q$lXmSBMGj>Qf`M6{Rm;)lyfF|h0MNDc> zJ@Pt9G5C~lDCTT1Mff9gvOsw}Npef2hnlQIf9=Gp!VYK zu(0qVVS}95^@4(BAz|M56Mxt5l^$R6HxE#!}C`gEq!W-zrnC@46fPt z0igedU_bHcY_(lvAGjbWp!dmYdh?ysj^L(KKHy3lPzdNS*do4*&SBEVz>h}VFM4w% z6zQ3+g1Vqs@mBGQFzrL^5l=4wVU?Z*0a;C&lBwECONr`7c(!RT4+t;U)grko3!0j= z;TqwqpFEP*xse?Xd;{aUf-`ZQ9gAOp(5*BEk0kBt%d;1f0Z+Q%_%1nS(RL3CWT=GS zEi@%H@(8QSDD|ae4x(ua>uSil(s@DXQ*?f$*-$+XLF%v!5;K`OA@8tx`WCCO3wUOq7IH|&vCX?j}8QA1nY`qnQbo( z7Qwwy(K5L%qBy@hQ^q*Bl(Mk0{P{w}sCMA8tQy&_A+Jl9rktI^;DqgpXZhu zA{<{u*KdQqHf8Ri*5=}_+m{xZRh@NR3-9MtO%>rb;^e}=b-W^MB|t+fY{bn`01mY-NJC(~M2uj_pWc9he2 zvKmFLER4fwTqX62AtR^K_H}a0Kh%EPKx+ z7iI!0#OrRHMCJ0H54x15v1#7FY1#3sRPx83ENvDLe*s*eDfD9UP%0_I07h}Uk8ueo z{%phjZGGk%WOz=D0$xP%gk`N;wT?LD?(dr@>U+6%_%a($?rhkigpQ*57Ta1iac{rb z+f|%@b9rQne`^L^ghl~W93P#B`*df_=G^AcJqcS4t0AIx+<1$ms~GQzGJdXc4hzWd z4?sW1ECxt#4<@KbyT;n1@|o3DC0PZ6nCg1le2)a0Y48G;!+V~?B}J%0x!o=m^VaI_ zzvf9E{9oF+D9zB=_M0)*3AfhMC)HUb?iT#8I6MV9C7d4}0(&&$Fuvz|GP|Ewpov80 zpPJ~U3$QN~BVsh-Mi|tB8eCV?+o6m1%UAZuPn#q!5Gth1OYa`3BKa!5c?{xa2t8jG z=V~ZX>7fR1qAV!yzs=hlzpYZL%@qB#)*9IDs8o0wCF5fT`vnFDLa%bMomIg_t>!oD zy6J_Bh?NBw@Lfek_OO=L^w}Wo+#}-e^q22c{u}N3!CqEnQjJ~6yQ+fkW;Y5YZ3Lu_ z!}@)cj~Ej>#}x$N6F+4nr`$WBN;g(~3RbYk#)vUCz0bo0&Y8yX2vawxSn zn~c}h*JBNAh)HrC$G?HCMmhhQ(p%FC90ju6p&~&Wa*XR+>eNbS9VNi)aH8EkzYSem z3XabrpA>J^aL)-?RT(X>KV%rImBKB{)=*byhSAGHYt1dWHfuUIsXFR3^)lTHVOnM+ z=G01wT1>j2JbJ(6^L1~oOFpbZN{Wzgo*NZPGB1*ge*74J@9fry} zmK*FTvy<-Gto`JV=Iv|J(=*ZQyP>*@;fHisd$N~>-ky>iMF z3@bfhQr*@bal%e7UQ0Mw>iz1J=4$-stW@6({SOSxs^)P#xNb>$AoovQnVn-Ak7cfb zI#aNVBjytgJfeHWOJQ?P`i(C};{sJjM&|)TQe3=IT|3%@XHUP*Z%oW^b35I^A^QmN z`ULJ`&iAIw!B(Ngr!8~-$gO2N48L=8F+2!08QH;Gt3PZgS`x5Xc_*Z{PY>64jiEw% zTw40xS181eh^__vf4RI-d>Ams+gv$O)QaEy^$sD08zBOC`crKw=Kg_FRBgGrPpmU% zO7wZlT6|6&=5Rjt|49!Wk_}}erfwo-3Y|V%?>2#?__ypJS@gkn}{W)BQEyRl<8eFIE-xOp#WFZCp0yOeTYa`wrrj`Tzx zu^pzvO4g~O;vRXRP5<-fR4kL#_1u>VI#B+Jjofem#nCubKW&C&;_U&cI(rn`n2OyI zFIiqvCu9*e86`wjH@=vHw{5=zLBL6Yx2K_2L29u4~EGD>-l79Oa_DG{jSt8|YUBjaRA z<55Ujh=iL^{Q0lpB49kX!tcO|VuJ%+rygw)%>2WIgr>zMh0A6)`JRTsjtsv73)&dVN zd_x=0s>1^-{xNO%fgkFxYVVh+2*kV|yzRmg2YQ%ePzcZp=MFz^o@YV*Xn%gRYsnV3 zoG?X6W38_h06g?q=rG0mCxHpmlq6#ukd+jP&~@#PX@ z;fHDUyYVIB70)`TZBjz^FBUs#ji(lhrJz~(x|Mix_Np)aR+t)l)yc1mpNOO;gGJL` zzxk1>exd6-;8^ARZOG~JwLhi;|BShixSwVMdXbU*ACPOQc^K6zmdA*9-p>PiuBT>~ z@TjtYBN8;8)B2J;5-|K5J@?MpsJJWT6XJP_PS4(mkLL+F|Ghkmc#?j}s-!JZou}^l zTyKCE=lVH|;qGq#k*b-EK5S%e%O$^_>E>d+BZYUpo2nx!ZKXeut46%%d(1{6Y)Y7p_G`XL|SDlDfbW=>v%bmoppa>20m?nO>#I8 zHO9zXCvBQNoDWMlGE$I8UNjPN_d&1v!Yf2@C*!8ETC?JXt)(z7Fj(w#nkZbP-8Pe$EeKjfF@g(5B#YuY`jbyK)0o{9Zt;dW^2>Jg$xRPwQuYV152T8>CdAK zR}ekWx`zkU0*Rj5tpj`3lf2G$v4d7GE?>qm<0VX+M`o!4>gxs|zwY&JbNUz(s6thv zWvMr!EPV`?(Xq?T?phd_AIq}vCaU`6^qXjfKU$;t8jbL-v(>pf_4<|&= zx`n3B{(jc*M(AAVrHdVFt*65;e>!K>t{`*eGwBYW>eiqc+Dq#lTQIl~PGS|vOJW6W zS&vZsR~u)P=WHANT52f}k&-Bz)^En&3=dL5BN%tyl@1EEPFMxq(=b3zbMEo0F5o=sArPc_l^kf(!=7BeE64UFfIj_&M@I1V_c9{^@ zevQUUG1E3)@(DC1WyMup^*-e$n|56l|Mr1XGpX!S*E?3djurP-$;HrQcRIj1TKK@L zDT)eKKE0joZ?~Gwu7de}ixekXe)Hau?P}NPtB+ewvI6(jibFy$qgD>oU}GiQ^fCcy z>%1RwGbO>%xuHmuk#bbc5*wHEh(7jqVp`o1&!If+YL*7aj_F4wBsZUf301`r}mSkGhM7rqSpqX<40M4&3PlR~NECT4CvMV9R^+q;0T>jJZ8 z0aNeah&`iLcxiv?7F6WFk`)JBNi<+#a4zZ_*es9W9 z)`6@=Rgtbk!4MRvM+}IQBwo^WZ-LY26_5pnOXCOfb^^VD5M3d=U4jpUje#-Pa)8v} zF-qGe6q!DJH|hd#c5Q8qi>Fb8wt(KmXbb$6cAL`g-*7H0Ob+o8Nh}8uts>!SzI;-8MjA7^8>nM`$dY4!YH)Id?a*n@q@zwIaQpn)FJB!q#ji3b+2aF!?1|R#)?xrmrY_L z|5z`eNB1m|ZwKryfP^=g%Yw;ejcy0a|u6x#Y?-Hl6ph*T&Ty1X1dk2@aQv1SZZ6@5ely2X;{AU(IRFN}7cofJy z>=(#p$Yk7YG%U(2&eXhu)I5cdqv<6yl`@Jg-oWcRW~@Gw^Sqdwc1Fq_-OPQHBrBOb zDfvp9)%w&ku5hfk;dgfWLgbxOVZjB0W$ws{dy0N?W{ec`Igs~ykJ};1;>4|4C#sYW za@Ks>d^4I(GWvcB?U849@QO&%b!)@v3oAdP=5}% z?tXmEm+5}gNsuX2b(6t4)@rwWG`j7x(%9Oh{$MP6`x5Gz-(%xw4HD_tadMpkFv$rD z#4TeVnJ&hiv8qX2uxM6P6J$?J=&K$Ya=Rx|kkyLdc05T`+UA(>{}wxK*Ant@{Tf^u zIu%D4Nd7RP?Kv-_Vv;gDhZ#|v*sgVEJOXCH%F^VTwE8HwNa=_W%Y{>@BqFwemGI>;KeeTPAv8H|UBPWRsKx_>F2mv5B0kTSlgdC! z3L&~D6`j<+qG9^V{9WC~aq%tzcM42pQmVw@P zFaYu#e5!Yr8)KU;&ZgGz#D^0rx|;K6CWanZA9d$|s$sPpuVdBs>jIW;{U~l50zI4% zZ)z|@*w(0)aY`TwBCs)ZNMxug_tl18W6STY{x2w-39$J{PJxnY0d$^6by=xKaO=?}^r* zF&+)APAsYAd4@X7xhN2z)BMko&Q>f5(xU_Gg6!pBIi%*AMOOCOQk!&` zMG0PZXj@mr{GLzT@OM16gtK}H=uwqCDlVwNVa|ujNGC-A3EHCpt$HbtJ=ST;^FVYt z&~D7SB_j)wI@HmD!EhvBLdWiPlU0)XJ!8(-&LNJn5*c<4X0sZ=J#Z z(Mhe|T|-|GeRte(>31(R8y(TenWK8V$+FFPZ`Je+ zT;+TvSZ*1z2#yU`UTQ`~%U>U_lL4mZTb8j+>pYH0Qxx#*V6e60B{I8Gmc-mx=_MV%TN(m?hl>0akeDFWzj7z zpbVL%CAkrC>nEtEKw}vkw1+|9uyxJ==l));`f2nh!jD4s2B+l*;01f+cjIVaByetq zO>MiDdhb@3FOgpBLSX13d)v*4+xj4(yM3j}xQ+eXnX@uW<>)}aST3^d5vKx_Ch zd5YLK&oW|m57c8Hpelgtu2bC+#~GMbbeFEjhpU{+2SvNPyZ;{DHtb((cj0{ZFuczDz>~fQ4laRj75y3g zDK54es*U_EqLhnaj(o~so9kVEeu|2N(N+#>`?PvrqHR1QHB)rn`2g| zg&)#3HJzKN+n=~n3Ix>;@CIa+b>u~D7mlv8OYjSn9~0#H{|L6X;42B*vtFTBwD><; zg2T$(FEt5erfT$r%XdJ9H&N$k!7kOFgmjzDh`_x#H>RDwYcDVBox6HbM-N?(0Ra%~ zEPz^)+2PvZ!gI`|7kWaQyaPAVOi~mdmYIM5v%s0}tFqv{EUn@u2f6haZ@hfd$7kk0 zx>fgvnUuu4;^68*-RwU{9!krolv8LztL%mBWsanKy`qAn0yh#LjMjPWpj8yH!8g*D zpA@vayQ>c=dY5hoFD66C#q^rbq_t8Qx2A7~`WSl3ug31&-FnjH0@YimViKiw^gOHw zmL1BrN{*~iPZUp)0LB%GGjgq?OF?-9ub#0islFw5a*;@+#39}W)r^x`MX z=Th_JKIE@t-8K-uEK|t2o>&~4*jg9hziMg{DI?RcF=HpT-`HU z$nE37QpMxfh7V_j4akYvF?i>_7VmOjd-{kWp6Bp*yN4}=F1NA4KXUf&_KKo z!Fj)-r`{ep;0mCqOB=Ll^a!>P^=bvhJGHZ}Bzb`TW80NzaS8#zaoPW4@F96iKOxNz zAPlx_0r+bKm+wGHKVX{$JHUaIRKpL^zks2dKTtX+F3Ov1|KGGN;sn{M6#;1ju1(`8 zFxLZ#FpkW}T#XJ6*Hy@P+Eq~w$t8nCcN{H};=WP4@q^HN$Bs7eqF?2hgLYMSfNI`d zs9hHWgU*Jzhxsi1KKrP9`7AirD^JVGW8*Yuc%m}eBst2;WX2|X3%V$hTCg<0Bd%3y zvi_JfA1hZkXuCAG#B!~%Ay7E2ufi+a=r0dv)w-Z;G?T@OioQw=miPW8Rfe;IzW-WO z$@6P2e!|Df_?f_kxYDKh)ZwtNQ}p64KC8FkYH457)m;Bo%@0+Q@|H`eJ{ z!k`VuNUDZ`KbjU!+$LOdw85ye(1amh!pzB|d}EC?bEESY60H!$B&Ic7GPz8gksMlUy#T?M&M=2WG!n{K14X6KAoh?i$-C)aZ`vtWPx2+DX}DX()-N1C;Z!g2XYa(9w+^P6Tg3)hd%SAlU6B+dM;>Isc%vq(ZCbv_n;PFfxEBTreG zj_{FuV)uI7)$+W9u$!xSmz3x$Wd1k@-v;MKZtAH_U41sIL_-Mw?f9BwGgefvikZ!1 zz0Bv@x@cslYFfh}y&zyXX5KZ%4-_MgqVQN0pcKXhL##CCr-aPmm!nKZ=kBK%MZP%~ za63UDH1O-eZ&i&`!fbtn^lX>p`|_nH_b&PAZ9%zdQp7HsP2TMoSj8ERBA#Px{O$2N ziUan|SqRSmypcuHF!{HnL7`GoGwiq!M%4Nq7-q6`X{PwZ$wr)6#K7BHTXf<$2`3aP z+SU`{Y8vh+=cpcZ17W$|-0(Vmd7)sL1d@EXs{4#JvGbUR5o{prn{dI&9=49o5J z7!M*-XIvg3E__3X+sVKhWb4*1hMlt3EE~hNZBx=)GNUHnGCtPoN^W93NGjd-!qWa5 z`w0Ua0)Ym@49`D5Jmvs|zQU zwaadr&Lpb^`W(nwq(;Cy!?R#IE{rx7bsEfi)(Km^e!I!hm4IfXM;$C9W2{0>UuD?r zTDYKYzrZ~{Ij%;4S#dDAdC5y{$r0Jft}uVe?D@29@Q_Tb<_cVf*L;mD$-TXlBcXiJ z9gnZE)|4(8VF%rP@X64Fm0OgLna~z2X>OGox|nAF$u=peNl|q!K-%+&GqpX`|LuL_ z2R|Nf2d#XlO!+vn9E6pjHLX>#92++1H0fgSQ_yEn1(ToSPaoR^%o;ykg6*)saeaV; z`nGvhl(`R6PAubObh3Y*Z}2Z1+j?Z|aSi|D6W4#v#)gXHKVL4%0{Q0+8&AUXoVVsa zH0C)uw6f;#|IWWPv@69k7+}!kkqUQ=9MkM=DW!;a@!8Hbg^Qv-O+9zZd7+`h#1zn- ze~H7k7r-6t@{7quk!8HFpKfC8Nr#&T6iD}c9eU?%d6W+coUPM^bho)GyJY_Qp!YEV z>ZfA954E-!U{6@a3{SGLUdZV!Ysze-YM#rQmoC4R(CzVk0{@@=LRwO+Fh}5E*i!Un zX2#kILU|=7gc)mlT5jR=Q2VWwzMS#qk5P$<1*f(RLD???jXLG9BFsUH-{;HvGXDzH zo-M3PnU@C_n5;U5)6VPvD$kGJgFj?_V;?u)e*#0|hJnaK5pYmGgC~jW=>Xtsu5Jow zbk8CQ$_z^fmh9d((4W91@Y@QG-d9=(=;Nb118U%qyxTXx1IONSo^iJhE+}ByqP<>f z*X$&`YsmT@bX<1BQJuCC$m4F2J}{`G!ENB$G_Cu-!XS1?N}N9sQ7262#-EE+oDR|Itk1BcoSO z_zf0y#1~#&AAK-ho%7&;^*?N!A;Y<#ay~5_l=Un`lm{uB>cn74aVn?f@?X zwF9ZI0lPUbz}TqvHbq)jAa@!1ikR%5)I0`Dcp#P>NiPzY3;;TNN}RY~_PHmh@6F$g zm#q{18`bvFAA#0(RxBV!HDLTQ%|t}qDlPr^8<`xHxtO#5l@#TJA*?>jkFK3T zrLH8&;ErK{V1x{sB45Z}ihI$Z^|;8_gig0Tm1M9Ee{P_uGQY_QIp8UF0Ud7fQ6K}T zTFHbPUnyxt*(t_Y_;dRFsi#iGwme1J_kHf(4s_{Sc~92duk;K4jAW7UBeZak5W@!H zf8EwB^Dk2__+9GT*4tKdhuVqzF?gQSt||aF7`OAzBk<;R0WGS0 zGppMofrSONJqT0$$3f5S0q&WMYVN~Q8+twLdyDHuT z{g=7K$9dLcD^zWSb9F>Wb@AeQrwLcoJwowlkd7SHyw&&ZOs`E_K;%EWux9$(cD7A0 zUzC&EhpGRpeDp|b53sjysVUW*-Wt+cYA>XJ1bgLyC)bACMQF0M2@?#w=h#u)D`Vx1 zD=bWR#PSLa`|KAk%jEH-CFAV4-MO^}jOg`b;7`g=YVY4YpZb`8PCtUWYtMo2xu2pXtKFwuV zt1I0M2i@~#%GgP|X<@mMUi=(<3GxMjN7jp=cg%gU><9(xj&i%LOV__mXxE&p9}Re- z+QW49-+$sX7QeAn7AN$KI!@TvCd_9YLlfKD_4tS3S!#)qfwuTv43=vhJBcMv6Mz(2 zk0&rKBL^ds@w;p-8Z+)>;~4=!QJuVAe-ZpB+JSllF$yG(=}}!bG$%@gttvzcx~<5+ z4n)3%%YT>5$mo}xXji6x0lRPQP3M6&oE!+LLDD!(ijybLHqRJka zXxKNy5R@^b&&bWd(tZHyZ@w=-zbvlDmnFVD&Ub9L5)sVQ!Dt${NL6X?rjAMBcT-oP zz$}7jcCnUfL78WCe*53pqYp(lMqC4)p8u+DGy()kzq>8S?h(hkbeVMum~sFV&c#a( zWvAG_eU4XGJbIcDdrLXU0;C=pmgjZ~IRK6q*N;!AY%q`}s(I>1=0Z zdeAw5JYq|u@p9>JYk%INk2*5+fn*G+Q$*#yKb~G*`lWAlMV4kcO#@M~%cJB-mRU6) z=Z#A@v#y4}H4#-4>tIHoyW*$Ef4xa7QsBjs8r-xVb6Z*9=g0eTCLLjDeJ?|s?LZq) z1PsAW+@o<9FK*9W|5ddUgi5r1#IzX^P(OL}j^8r)_P^((*TsuYOx)3#+ca_iML1VU zTlZBv{JF&&1`d_4MD;}Luot2tt7r&ds`j7o|X*AFY2K7Pr$q6 zXw}Ik+>9hV6}U-<2m4!_5c)fYhW9-CVP2vUo|5aSHd0U5Tv)r)cDYk;CL<#yezYyZ zpd0@}6WI;FFb_jrhVGb4N1Ym}PCa$$n6^Iny>Ns(cZe2iAikOtiPN$XOV_yeq`Jh< zvStV=xPv&e$!CQHwF<$6j06X@2jxcob>mcH9t%dx3p^gb`TFDb5xlm(8BGY(7S3N3 zH!yHvJ#- z^8it3J+alq?L$XsWVpXbTczC0N+9l%!3oa+9}diGN7?EQ(X2}EC)!`a|6*4FEje3dr zleC+3=9`>m#TlVPiHfaUN%GABgX^?m(OHfnT2u8GtGdc?omHA*OSy zUBa%w?1uReY0x+9*l|kW-zp000e`h*SrHXnLge}bJ_Y7QSCdc8RE^47H1+EUbVXc_tm zQ8keaXLelEz0n+lGOmzAzNc+5cOZCB=8e`%v55-3{v&NMj>Iuw1I`88MuC)DyE1CHWsXI#gi6guku#m-Ct*+1&)=x>MQ{b$S2-4CFLC)fpe+$%*J zT-`~-CAOb2txTYH376?H+%j%HheiYm5(sZeSYUY8nns z#fTj&`mXZNFs9JvQUioKZ{z^qaedgyoMy0BwaI$+D%T!I$~+gc1{k89N9SPRw~I2i z(xpvO3)KWeyLa^Gf3B&2P(S^G=A&0(-t52`Jbf*xImO?tU(8FHBc>Qq8HN;6m44*_ zBh_7BYxO+8y^fhz1?~EDx{s+{)9X|p#kt6 zT~dcym&wmb;Hg8P#aQdsx+AKJU%-qre&#-JcYvd5VG6i)d!Ad33ww0mhr%||1KoT8|!h+eQ$$8&{$jv%?b6LV(d9Nu==Ck ztsJUvIix2Sr0|GGK0dE!x$ZfnWOXC6ilEiLXD^zW^Pxo>rAVI(OtPGbvk@pBh!los z7nhYPc*zN5`#EzLjyre!u+spk4O(btS?lZWxg>ncF!=1HWGr(&MJdZU(qf;?{mC|W z_OsUe6K~C$9mhbD0r^z}F|#hqR_g{KNwto$1paU>#(upwHJOk**ka?=?rIei=cntX z14tau!fA4H3>P6KQOcIXWE49=#iTI@vT-#PxcmI}j$RNxH7@OJrGlb2nZI{^dYq6(gSAze*=8CwBKa@?$yn827(NI+O ze1Exv+IUnZyY1?wdJ+)$JHeH#1jhk|r93ETqBquGC@?0?r2bK066)bwTO-s_0CHaC zTHRZ@a{&OUCFqyskKIu4z(n5lg_XWSGujEzqT zozBSdJ}i;T{O53;vtMc_5s9`UO_AV*;ZD3YUc^K$iXDm?2| zY&tb}sZ(bJSLQ|yA*_G9pa+ce9;T&o_V4ZI%Gtiie_e#w90qg~HNXK1fomXfbj^50uWGGKNLt?@>e2itN@KN75{ZL)%lqG|NFR52l3~r z0FpG!;6XL`l{uTPSsHLcPEd3G{;4ju^L9X?Q2752gb~GtqK>eXCBU}ctv95~gk`Bd zf-T|Ee)bKjlC@4aK0dyDN z5@<5{u??kEhw{#WAG=G+)JV((m3P`p+v{-VY@klLxTFB!iwvjjj1H@g!n>&M9IF~}C^|6}Pq!;*a5w{O$R z(iW*Xs5C82&226!bEoFslDQ={_XwdfwVbJ`uTJI0&K=}#CDa<(YCqM>sF96e-LIm~m>=MC%gw7;amcG2h{uPXBnN;UlG)AG}MyhND!WsdtZc*Hb4uS|gv13WTaMNbRnKWgnKcitE|0@dfYz zDx?hYXRhWFrQD@JsCJ&?+Jgk#^>Sux(PY<;mg=fR(=Q3Njr5YXmSFLCA)%ZsvLUQr zxD0_T{=1H{=aY#>icSvFwnER4I4JODs^zhiLYGEiufYr(`UTbYOZA$=6bQC;RlQfM!@Ii9RJDx+-2V%=qPn@c z@q~uqXa%XBoz}>UGaK$HR~ojQq2DTk7fz_QY&uYasVa-vQ)tTPbc?YZ(L$M_-cmcw z%UTcSpG|)G(FOJgU1!%c{yP*IL!<-d?g^+_;)t%OKYG*A!6;L)u26@qAboS}2)aK? z0aNb-o;}ZOeJZTX)58A}^qG_mJxW`kS9vL<$;_O7wavD94C{JH)>DYgxpl~T;v`Vp z3-5zkfp$O(;;I56aCB18L#uIwC&cCYk+Lkwy&jE=F$(KVA}U|_55|$LLPv~TKRP(s zqvD}7Q2%7rPYYixFigqX92wu~9RFBJ%J4rVpmKFq*Z12FO{t~8ReFIG@UxIPGAk1$ z8k>MC(YgNGPBA2kQSueBgS`rw&!HSKikn~09b8MLna8*8xi@c59jJzV{*mEU(1`6K zqdqcK#{^00X`!Xd(zhT@2GD#2)e5}-zlP_C822}u(-O^)```MH*th>!G@(B#Fp^0K zpaq)+@M}dKCdED2)B}hjpdi#RZ#54gZUxzTtn8)e$vvIBQ-^%JBRX$J>dZS7Ovk2< z^cWCPP1t#K5g3QK&OD^N&Zfy>&i(pDh9++Woo(5Q^LXi&M?(}Q$K|s|6-{n1Cie8Y^M7_j;w&!kI~ ztlP=#TI7=8>ORVZdY2^8uF6f4%YIupr|seIb1+9N8Ej(t)**rIh-RMfZRPsfNQ!XF&;Dg zN>F}=VmNMFJgTp!3f6Mr1TJ%bA7x`bQNU<^ZjJR{_4~c;lwBT}&B2rm5+E=bh3POp zOf5_}-HVrS^| zwcjegrH`x&-UG8}pZX`mWN|cADo_{gi&GVJPYqO68lzx)yquYrkui8vV%8tBakGWB zUxI$YqmxDR{E@_4;6Duk;k7M@#f8XTZ|R;;v?OG_<(T3;Qnu~vC25X)&6J&pYH#!l zy%PQabFC=Jx~d{~o=@%RNUu&_M!?DX@<5{`!@6UU#&WvaYo&J#Ds#txC2qDwMRWto z+2JJ~c?X@^^=FA7OWN)DJDz&TWz@ueA&vY-p}}+xFexXFd`ygLbV&}HYES#HaaAI% z$7H_vNh`gSM{Cqe!e7fs8?DiI>QY$tFd79{k*sw@{kX>qPi4)E6*%$>h}97B@`&GYO5*H* zZnwZA-RKMv)bMTKeH?mizYOO5qF`$l`!Kid0A{>e$W}q)TWwRhV8FJXFgI6KttJ2D z{0rq_DJkzEO(^_jpny2Jof9KQLZ^sx=a}97_kM6)cM%LSxSLn4)ql4g$Md~Gb{sJ< z2jpitgf_ZP@~Gh8nRAQ;rb=mVd0f0`Q9i0~iX%b)>T;=`4?U}}1kODo6gN|Q9y>

o^1?)&%uv7A^X2@f|Q0QPLF^^? zph1O{l3~P<_sUVX-(d17;jS+f{@TU4t90ukO_Hcttk97W&Hj+{cy+P`@Lk{}=uS7n zHil+6=&4C`(O%}gi5lefgMo&dF$6GWsC4rexlRPS08Lj_1BFH9-!@WE3h*7%vs{@z~qi>LIe9e{snTF;*8r1`MO;mf1$s z4BGf@Z5j1Uu8k~dAaGSR+aWNR`QCMRsU7P2!be{GfbUTEUWP5MYdX)r#)ErptH)UGJJYV?)YKSJ>_8Xh=D{sFT= z-Oj3<6ZP&A=&h(`p2wHS(6XA?Tr$Pg;yW8imoc{ftALY*Pr+JKCK~O<5Zufi%S(rO zs%E^mu#-)6du_2Z{pj?(KMvfJ36sw#xjvsYCWK~FiAK%7=ASblmK6F8iZ?slty~`G zzuOc+$_+-mKDeO35d9Hpo2Kj77oBlv*zePra;^O}_ATt?tGb^e%YlSty69-CZ@0-} zP35p_$Wj;;?Y#yW%(rF^eXo#i@>$Jd1*PUR*1R>RYUo)uw8RZ@FMWC79ouJMZ?khK znxYa5>;T-bUTcKe&OEQ2`lI^F9QA9l8HSs?x!de!|7N_*W841g1GjfR3QHsl2nZpp zO|UiS4(|()TU|D!+dfh@Q~3f=6ztx#JTFmg5&hd{-w?X)b;LF9Rw}4SXm9-Zcboiq z^*EXds?6yq;u_Z$n#8O%GrtB|w~0M?o5wAXwx(*~7ν5qic=WYF=sJwGlHV7A>F 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�+%{J4bcp~7@ubq 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 ZS2=0^r}3h@>1P;)1e0HJl(6x+|Jk!)inss( literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js new file mode 100644 index 0000000..cf05f1b --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js @@ -0,0 +1,502 @@ +!function ($) { + + /* CHECKBOX PUBLIC CLASS DEFINITION + * ============================== */ + + var Checkbox = function (element, options) { + this.init(element, options); + } + + Checkbox.prototype = { + + constructor: Checkbox + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.checkbox.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.checkbox'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checked = $el.prop(ch) + , e = $.Event('toggle') + + if ($el.prop('disabled') == false) { + $parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.prop(ch, ch); + $el.trigger(e).trigger('change'); + } + } + + , setCheck: function (option) { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checkAction = option == 'check' ? true : false + , e = $.Event(option) + + $parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e).trigger('change'); + } + + } + + + /* CHECKBOX PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.checkbox + + $.fn.checkbox = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('checkbox') + , options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.checkbox.defaults = { + template: '' + } + + + /* CHECKBOX NO CONFLICT + * ================== */ + + $.fn.checkbox.noConflict = function () { + $.fn.checkbox = old; + return this; + } + + + /* CHECKBOX DATA-API + * =============== */ + + $(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) { + var $checkbox = $(e.target); + if (e.target.tagName != "A") { + e && e.preventDefault() && e.stopPropagation(); + if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox'); + $checkbox.find(':checkbox').checkbox('toggle'); + } + }); + + $(function () { + $('[data-toggle="checkbox"]').each(function () { + var $checkbox = $(this); + $checkbox.checkbox(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================= + * flatui-radio v0.0.3 + * ============================================================ */ + +!function ($) { + + /* RADIO PUBLIC CLASS DEFINITION + * ============================== */ + + var Radio = function (element, options) { + this.init(element, options); + } + + Radio.prototype = { + + constructor: Radio + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.radio.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.radio'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , checked = $el.prop(ch) + , $parent = $el.closest('.radio') + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]') + , e = $.Event('toggle') + + if ($el.prop(d) == false) { + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + if ($el.prop(d) == false) { + $parent.removeClass(ch) && $el.removeAttr(ch).trigger('change'); + } + }); + + if (checked == false) $parent.addClass(ch) && $el.prop(ch, true); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + } + + , setCheck: function (option) { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.radio') + , checkAction = option == 'check' ? true : false + , checked = $el.prop(ch) + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]') + , e = $.Event(option) + + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + $parent.removeClass(ch) && $el.removeAttr(ch); + }); + + $parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + + } + + + /* RADIO PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.radio + + $.fn.radio = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('radio') + , options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('radio', (data = new Radio(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.radio.defaults = { + template: '' + } + + + /* RADIO NO CONFLICT + * ================== */ + + $.fn.radio.noConflict = function () { + $.fn.radio = old; + return this; + } + + + /* RADIO DATA-API + * =============== */ + + $(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) { + var $radio = $(e.target); + e && e.preventDefault() && e.stopPropagation(); + if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio'); + $radio.find(':radio').radio('toggle'); + }); + + $(function () { + $('[data-toggle="radio"]').each(function () { + var $radio = $(this); + $radio.radio(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ + +!function ($) { + "use strict"; + + $.fn['bootstrapSwitch'] = function (method) { + var methods = { + init: function () { + return this.each(function () { + var $element = $(this) + , $div + , $switchLeft + , $switchRight + , $label + , myClasses = "" + , classes = $element.attr('class') + , color + , moving + , onLabel = "ON" + , offLabel = "OFF" + , icon = false; + + $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { + if (classes.indexOf(el) >= 0) + myClasses = el; + }); + + $element.addClass('has-switch'); + + if ($element.data('on') !== undefined) + color = "switch-" + $element.data('on'); + + if ($element.data('on-label') !== undefined) + onLabel = $element.data('on-label'); + + if ($element.data('off-label') !== undefined) + offLabel = $element.data('off-label'); + + if ($element.data('icon') !== undefined) + icon = $element.data('icon'); + + $switchLeft = $('') + .addClass("switch-left") + .addClass(myClasses) + .addClass(color) + .html(onLabel); + + color = ''; + if ($element.data('off') !== undefined) + color = "switch-" + $element.data('off'); + + $switchRight = $('') + .addClass("switch-right") + .addClass(myClasses) + .addClass(color) + .html(offLabel); + + $label = $('

')).parent().data('animated', false); + + if ($element.data('animated') !== false) + $div.addClass('switch-animate').data('animated', true); + + $div + .append($switchLeft) + .append($label) + .append($switchRight); + + $element.find('>div').addClass( + $element.find('input').is(':checked') ? 'switch-on' : 'switch-off' + ); + + if ($element.find('input').is(':disabled')) + $(this).addClass('deactivate'); + + var changeStatus = function ($this) { + $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click'); + }; + + $element.on('keydown', function (e) { + if (e.keyCode === 32) { + e.stopImmediatePropagation(); + e.preventDefault(); + changeStatus($(e.target).find('span:first')); + } + }); + + $switchLeft.on('click', function (e) { + changeStatus($(this)); + }); + + $switchRight.on('click', function (e) { + changeStatus($(this)); + }); + + $element.find('input').on('change', function (e) { + var $this = $(this) + , $element = $this.parent() + , thisState = $this.is(':checked') + , state = $element.is('.switch-off'); + + e.preventDefault(); + + $element.css('left', ''); + + if (state === thisState) { + + if (thisState) + $element.removeClass('switch-off').addClass('switch-on'); + else $element.removeClass('switch-on').addClass('switch-off'); + + if ($element.data('animated') !== false) + $element.addClass("switch-animate"); + + $element.parent().trigger('switch-change', {'el': $this, 'value': thisState}) + } + }); + + $element.find('label').on('mousedown touchstart', function (e) { + var $this = $(this); + moving = false; + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.closest('div').removeClass('switch-animate'); + + if ($this.closest('.has-switch').is('.deactivate')) + $this.unbind('click'); + else { + $this.on('mousemove touchmove', function (e) { + var $element = $(this).closest('.switch') + , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left + , percent = (relativeX / $element.width()) * 100 + , left = 25 + , right = 75; + + moving = true; + + if (percent < left) + percent = left; + else if (percent > right) + percent = right; + + $element.find('>div').css('left', (percent - right) + "%") + }); + + $this.on('click touchend', function (e) { + var $this = $(this) + , $target = $(e.target) + , $myCheckBox = $target.siblings('input'); + + e.stopImmediatePropagation(); + e.preventDefault(); + + $this.unbind('mouseleave'); + + if (moving) + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)); + else $myCheckBox.prop("checked", !$myCheckBox.is(":checked")); + + moving = false; + $myCheckBox.trigger('change'); + }); + + $this.on('mouseleave', function (e) { + var $this = $(this) + , $myCheckBox = $this.siblings('input'); + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.unbind('mouseleave'); + $this.trigger('mouseup'); + + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change'); + }); + + $this.on('mouseup', function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + + $(this).unbind('mousemove'); + }); + } + }); + } + ); + }, + toggleActivation: function () { + $(this).toggleClass('deactivate'); + }, + isActive: function () { + return !$(this).hasClass('deactivate'); + }, + setActive: function (active) { + if (active) + $(this).removeClass('deactivate'); + else $(this).addClass('deactivate'); + }, + toggleState: function (skipOnChange) { + var $input = $(this).find('input:checkbox'); + $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange); + }, + setState: function (value, skipOnChange) { + $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange); + }, + status: function () { + return $(this).find('input:checkbox').is(':checked'); + }, + destroy: function () { + var $div = $(this).find('div') + , $checkbox; + + $div.find(':not(input:checkbox)').remove(); + + $checkbox = $div.children(); + $checkbox.unwrap().unwrap(); + + $checkbox.unbind('change'); + + return $checkbox; + } + }; + + if (methods[method]) + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + else if (typeof method === 'object' || !method) + return methods.init.apply(this, arguments); + else + $.error('Method ' + method + ' does not exist!'); + }; +}(jQuery); + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-notify.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-notify.js new file mode 100644 index 0000000..f2f0c74 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-notify.js @@ -0,0 +1,404 @@ +/* + + + + Creative Tim Modifications + + Lines: 239, 240 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically + Line:242 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon. + + + + +*/ + + +/* +* Project: Bootstrap Notify = v3.1.5 +* Description: Turns standard Bootstrap alerts into "Growl-like" notifications. +* Author: Mouse0270 aka Robert McIntosh +* License: MIT License +* Website: https://github.com/mouse0270/bootstrap-growl +*/ + +/* global define:false, require: false, jQuery:false */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + // Create the defaults once + var defaults = { + element: 'body', + position: null, + type: "info", + allow_dismiss: true, + allow_duplicates: true, + newest_on_top: false, + showProgressbar: false, + placement: { + from: "top", + align: "right" + }, + offset: 20, + spacing: 10, + z_index: 1031, + delay: 5000, + timer: 1000, + url_target: '_blank', + mouse_over: null, + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + onShow: null, + onShown: null, + onClose: null, + onClosed: null, + icon_type: 'class', + template: '' + }; + + String.format = function () { + var str = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + str = str.replace(RegExp("\\{" + (i - 1) + "\\}", "gm"), arguments[i]); + } + return str; + }; + + function isDuplicateNotification(notification) { + var isDupe = false; + + $('[data-notify="container"]').each(function (i, el) { + var $el = $(el); + var title = $el.find('[data-notify="title"]').text().trim(); + var message = $el.find('[data-notify="message"]').html().trim(); + + // The input string might be different than the actual parsed HTML string! + // (
vs
for example) + // So we have to force-parse this as HTML here! + var isSameTitle = title === $("
" + notification.settings.content.title + "
").html().trim(); + var isSameMsg = message === $("
" + notification.settings.content.message + "
").html().trim(); + var isSameType = $el.hasClass('alert-' + notification.settings.type); + + if (isSameTitle && isSameMsg && isSameType) { + //we found the dupe. Set the var and stop checking. + isDupe = true; + } + return !isDupe; + }); + + return isDupe; + } + + function Notify(element, content, options) { + // Setup Content of Notify + var contentObj = { + content: { + message: typeof content === 'object' ? content.message : content, + title: content.title ? content.title : '', + icon: content.icon ? content.icon : '', + url: content.url ? content.url : '#', + target: content.target ? content.target : '-' + } + }; + + options = $.extend(true, {}, contentObj, options); + this.settings = $.extend(true, {}, defaults, options); + this._defaults = defaults; + if (this.settings.content.target === "-") { + this.settings.content.target = this.settings.url_target; + } + this.animations = { + start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart', + end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend' + }; + + if (typeof this.settings.offset === 'number') { + this.settings.offset = { + x: this.settings.offset, + y: this.settings.offset + }; + } + + //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing + if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) { + this.init(); + } + } + + $.extend(Notify.prototype, { + init: function () { + var self = this; + + this.buildNotify(); + if (this.settings.content.icon) { + this.setIcon(); + } + if (this.settings.content.url != "#") { + this.styleURL(); + } + this.styleDismiss(); + this.placement(); + this.bind(); + + this.notify = { + $ele: this.$ele, + update: function (command, update) { + var commands = {}; + if (typeof command === "string") { + commands[command] = update; + } else { + commands = command; + } + for (var cmd in commands) { + switch (cmd) { + case "type": + this.$ele.removeClass('alert-' + self.settings.type); + this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type); + self.settings.type = commands[cmd]; + this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]); + break; + case "icon": + var $icon = this.$ele.find('[data-notify="icon"]'); + if (self.settings.icon_type.toLowerCase() === 'class') { + $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]); + } else { + if (!$icon.is('img')) { + $icon.find('img'); + } + $icon.attr('src', commands[cmd]); + } + break; + case "progress": + var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100)); + this.$ele.data('notify-delay', newDelay); + this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%'); + break; + case "url": + this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]); + break; + case "target": + this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]); + break; + default: + this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]); + } + } + var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y); + self.reposition(posX); + }, + close: function () { + self.close(); + } + }; + + }, + buildNotify: function () { + var content = this.settings.content; + this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target)); + this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align); + if (!this.settings.allow_dismiss) { + this.$ele.find('[data-notify="dismiss"]').css('display', 'none'); + } + if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) { + this.$ele.find('[data-notify="progressbar"]').remove(); + } + }, + setIcon: function () { + + this.$ele.addClass('alert-with-icon'); + + if (this.settings.icon_type.toLowerCase() === 'class') { + this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon); + } else { + if (this.$ele.find('[data-notify="icon"]').is('img')) { + this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon); + } else { + this.$ele.find('[data-notify="icon"]').append('Notify Icon'); + } + } + }, + styleDismiss: function () { + this.$ele.find('[data-notify="dismiss"]').css({ + position: 'absolute', + right: '10px', + top: '50%', + marginTop: '-13px', + zIndex: this.settings.z_index + 2 + }); + }, + styleURL: function () { + this.$ele.find('[data-notify="url"]').css({ + backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)', + height: '100%', + left: 0, + position: 'absolute', + top: 0, + width: '100%', + zIndex: this.settings.z_index + 1 + }); + }, + placement: function () { + var self = this, + offsetAmt = this.settings.offset.y, + css = { + display: 'inline-block', + margin: '0px auto', + position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'), + transition: 'all .5s ease-in-out', + zIndex: this.settings.z_index + }, + hasAnimation = false, + settings = this.settings; + + $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { + offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing)); + }); + if (this.settings.newest_on_top === true) { + offsetAmt = this.settings.offset.y; + } + css[this.settings.placement.from] = offsetAmt + 'px'; + + switch (this.settings.placement.align) { + case "left": + case "right": + css[this.settings.placement.align] = this.settings.offset.x + 'px'; + break; + case "center": + css.left = 0; + css.right = 0; + break; + } + this.$ele.css(css).addClass(this.settings.animate.enter); + $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function (index, prefix) { + self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1; + }); + + $(this.settings.element).append(this.$ele); + + if (this.settings.newest_on_top === true) { + offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight(); + this.reposition(offsetAmt); + } + + if ($.isFunction(self.settings.onShow)) { + self.settings.onShow.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + } + }, 600); + }, + bind: function () { + var self = this; + + this.$ele.find('[data-notify="dismiss"]').on('click', function () { + self.close(); + }); + + this.$ele.mouseover(function () { + $(this).data('data-hover', "true"); + }).mouseout(function () { + $(this).data('data-hover', "false"); + }); + this.$ele.data('data-hover', "false"); + + if (this.settings.delay > 0) { + self.$ele.data('notify-delay', self.settings.delay); + var timer = setInterval(function () { + var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer; + if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") { + var percent = ((self.settings.delay - delay) / self.settings.delay) * 100; + self.$ele.data('notify-delay', delay); + self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%'); + } + if (delay <= -(self.settings.timer)) { + clearInterval(timer); + self.close(); + } + }, self.settings.timer); + } + }, + close: function () { + var self = this, + posX = parseInt(this.$ele.css(this.settings.placement.from)), + hasAnimation = false; + + this.$ele.data('closing', 'true').addClass(this.settings.animate.exit); + self.reposition(posX); + + if ($.isFunction(self.settings.onClose)) { + self.settings.onClose.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + $(this).remove(); + if ($.isFunction(self.settings.onClosed)) { + self.settings.onClosed.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + self.$ele.remove(); + if (self.settings.onClosed) { + self.settings.onClosed(self.$ele); + } + } + }, 600); + }, + reposition: function (posX) { + var self = this, + notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])', + $elements = this.$ele.nextAll(notifies); + if (this.settings.newest_on_top === true) { + $elements = this.$ele.prevAll(notifies); + } + $elements.each(function () { + $(this).css(self.settings.placement.from, posX); + posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight(); + }); + } + }); + + $.notify = function (content, options) { + var plugin = new Notify(this, content, options); + return plugin.notify; + }; + $.notifyDefaults = function (options) { + defaults = $.extend(true, {}, defaults, options); + return defaults; + }; + $.notifyClose = function (command) { + if (typeof command === "undefined" || command === "all") { + $('[data-notify]').find('[data-notify="dismiss"]').trigger('click'); + } else { + $('[data-notify-position="' + command + '"]').find('[data-notify="dismiss"]').trigger('click'); + } + }; + +})); diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-select.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-select.js new file mode 100644 index 0000000..a9ee735 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap-select.js @@ -0,0 +1,438 @@ +!function($) { + var Selectpicker = function(element, options, e) { + if (e ) { + e.stopPropagation(); + e.preventDefault(); + } + this.$element = $(element); + this.$newElement = null; + this.button = null; + + //Merge defaults, options and data-attributes to make our options + this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options); + + //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute + if(this.options.title==null) + this.options.title = this.$element.attr('title'); + + //Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.init(); + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function (e) { + var _this = this; + this.$element.hide(); + this.multiple = this.$element.prop('multiple'); + + + var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : ''; + var id = this.$element.attr('id'); + this.$element.after( this.createView() ); + this.$newElement = this.$element.next('.select'); + var select = this.$newElement; + var menu = this.$newElement.find('.dropdown-menu'); + var menuArrow = this.$newElement.find('.dropdown-arrow'); + var menuA = menu.find('li > a'); + var liHeight = select.addClass('open').find('.dropdown-menu li > a').outerHeight(); + select.removeClass('open'); + var divHeight = menu.find('li .divider').outerHeight(true); + var selectOffset_top = this.$newElement.offset().top; + var size = 0; + var menuHeight = 0; + var selectHeight = this.$newElement.outerHeight(); + this.button = this.$newElement.find('> button'); + if (id !== undefined) { + this.button.attr('id', id); + $('label[for="' + id + '"]').click(function(){ select.find('button#'+id).focus(); }) + } + for (var i = 0; i < classList.length; i++) { + if(classList[i] != 'selectpicker') { + this.$newElement.addClass(classList[i]); + } + } + //If we are multiple, then add the show-tick class by default + if(this.multiple) { + this.$newElement.addClass('select-multiple'); + } + this.button.addClass(this.options.style); + menu.addClass(this.options.menuStyle); + menuArrow.addClass(function() { + if (_this.options.menuStyle) { + return _this.options.menuStyle.replace('dropdown-', 'dropdown-arrow-'); + } + }); + this.checkDisabled(); + this.checkTabIndex(); + this.clickListener(); + var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width')); + if (this.options.size == 'auto') { + + // Creative Tim Changes: We changed the regular function made in bootstrap-select with this function so the getSize() will not be triggered one million times per second while you scroll. + + var getSize = debounce(function() { + var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop(); + var windowHeight = $(window).innerHeight(); + var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2; + var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras; + menuHeight = selectOffset_bot; + if (select.hasClass('dropup')) { + menuHeight = selectOffset_top_scroll - menuExtras; + } + //limit menuHeight to 300px to have a smooth transition with cubic bezier on dropdown + if(menuHeight >= 300){ + menuHeight = 300; + } + + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : liHeight * 3 + 'px'}); + + }, 50); + + getSize; + $(window).on('scroll', getSize); + $(window).on('resize', getSize); + + if (window.MutationObserver) { + new MutationObserver(getSize).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', getSize); + } + } else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) { + var optIndex = menu.find("li > *").filter(':not(.divider)').slice(0,this.options.size).last().parent().index(); + var divLength = menu.find("li").slice(0,optIndex + 1).find('.divider').length; + menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding; + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'scroll'}); + //console.log('sunt in if'); + } + + // Listen for updates to the DOM and re render... (Use Mutation Observer when availiable) + if (window.MutationObserver) { + new MutationObserver($.proxy(this.reloadLi, this)).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this)); + } + + this.render(); + }, + + createDropdown: function() { + var drop = + "
" + + "" + + "" + + "" + + "
"; + + return $(drop); + }, + + + createView: function() { + var $drop = this.createDropdown(); + var $li = this.createLi(); + $drop.find('ul').append($li); + return $drop; + }, + + reloadLi: function() { + //Remove all children. + this.destroyLi(); + //Re build + $li = this.createLi(); + this.$newElement.find('ul').append( $li ); + //render view + this.render(); + }, + + destroyLi:function() { + this.$newElement.find('li').remove(); + }, + + createLi: function() { + + var _this = this; + var _li = []; + var _liA = []; + var _liHtml = ''; + + this.$element.find('option').each(function(){ + _li.push($(this).text()); + }); + + this.$element.find('option').each(function(index) { + //Get the class and text for the option + var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : ''; + var text = $(this).text(); + var subtext = $(this).data('subtext') !== undefined ? ''+$(this).data('subtext')+'' : ''; + + //Append any subtext to the main text. + text+=subtext; + + if ($(this).parent().is('optgroup') && $(this).data('divider') != true) { + if ($(this).index() == 0) { + //Get the opt group label + var label = $(this).parent().attr('label'); + var labelSubtext = $(this).parent().data('subtext') !== undefined ? ''+$(this).parent().data('subtext')+'' : ''; + label += labelSubtext; + + if ($(this)[0].index != 0) { + _liA.push( + '
'+ + '
'+label+'
'+ + _this.createA(text, "opt " + optionClass ) + ); + } else { + _liA.push( + '
'+label+'
'+ + _this.createA(text, "opt " + optionClass )); + } + } else { + _liA.push( _this.createA(text, "opt " + optionClass ) ); + } + } else if ($(this).data('divider') == true) { + _liA.push('
'); + } else if ($(this).data('hidden') == true) { + _liA.push(''); + } else { + _liA.push( _this.createA(text, optionClass ) ); + } + }); + + if (_li.length > 0) { + for (var i = 0; i < _li.length; i++) { + var $option = this.$element.find('option').eq(i); + _liHtml += "
  • " + _liA[i] + "
  • "; + } + } + + //If we dont have a selected item, and we dont have a title, select the first element so something is set in the button + if(this.$element.find('option:selected').length==0 && !_this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return $(_liHtml); + }, + + createA:function(test, classes) { + return '' + + '' + test + '' + + ''; + + }, + + render:function() { + var _this = this; + + //Set width of select + if (this.options.width == 'auto') { + var ulWidth = this.$newElement.find('.dropdown-menu').css('width'); + this.$newElement.css('width',ulWidth); + } else if (this.options.width && this.options.width != 'auto') { + this.$newElement.css('width',this.options.width); + } + + //Update the LI to match the SELECT + this.$element.find('option').each(function(index) { + _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') ); + _this.setSelected(index, $(this).is(':selected') ); + }); + + + + var selectedItems = this.$element.find('option:selected').map(function(index,value) { + if($(this).attr('title')!=undefined) { + return $(this).attr('title'); + } else { + return $(this).text(); + } + }).toArray(); + + //Convert all the values into a comma delimited string + var title = selectedItems.join(", "); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) { + var max = _this.options.selectedTextFormat.split(">"); + if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) { + title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected'; + } + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if(!title) { + title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText; + } + + this.$element.next('.select').find('.filter-option').html( title ); + }, + + + + setSelected:function(index, selected) { + if(selected) { + this.$newElement.find('li').eq(index).addClass('selected'); + } else { + this.$newElement.find('li').eq(index).removeClass('selected'); + } + }, + + setDisabled:function(index, disabled) { + if(disabled) { + this.$newElement.find('li').eq(index).addClass('disabled'); + } else { + this.$newElement.find('li').eq(index).removeClass('disabled'); + } + }, + + checkDisabled: function() { + if (this.$element.is(':disabled')) { + this.button.addClass('disabled'); + this.button.click(function(e) { + e.preventDefault(); + }); + } + }, + + checkTabIndex: function() { + if (this.$element.is('[tabindex]')) { + var tabindex = this.$element.attr("tabindex"); + this.button.attr('tabindex', tabindex); + } + }, + + clickListener: function() { + var _this = this; + + $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); + + + + this.$newElement.on('click', 'li a', function(e){ + var clickedIndex = $(this).parent().index(), + $this = $(this).parent(), + $select = $this.parents('.select'); + + + //Dont close on multi choice menu + if(_this.multiple) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Dont run if we have been disabled + if ($select.prev('select').not(':disabled') && !$(this).parent().hasClass('disabled')){ + //Deselect all others if not multi select box + if (!_this.multiple) { + $select.prev('select').find('option').removeAttr('selected'); + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + //Else toggle the one we have chosen if we are multi selet. + else { + var selected = $select.prev('select').find('option').eq(clickedIndex).prop('selected'); + + if(selected) { + $select.prev('select').find('option').eq(clickedIndex).removeAttr('selected'); + } else { + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + } + + + $select.find('.filter-option').html($this.text()); + $select.find('button').focus(); + + // Trigger select 'change' + $select.prev('select').trigger('change'); + } + + }); + + this.$newElement.on('click', 'li.disabled a, li dt, li .divider', function(e) { + e.preventDefault(); + e.stopPropagation(); + $select = $(this).parent().parents('.select'); + $select.find('button').focus(); + }); + + this.$element.on('change', function(e) { + _this.render(); + }); + }, + + val:function(value) { + + if(value!=undefined) { + this.$element.val( value ); + + this.$element.trigger('change'); + return this.$element; + } else { + return this.$element.val(); + } + } + + }; + + $.fn.selectpicker = function(option, event) { + //get the args of the outer function.. + var args = arguments; + var value; + var chain = this.each(function () { + var $this = $(this), + data = $this.data('selectpicker'), + options = typeof option == 'object' && option; + + if (!data) { + $this.data('selectpicker', (data = new Selectpicker(this, options, event))); + } else { + for(var i in option) { + data[i]=option[i]; + } + } + + if (typeof option == 'string') { + //Copy the value of option, as once we shift the arguments + //it also shifts the value of option. + property = option; + if(data[property] instanceof Function) { + [].shift.apply(args); + value = data[property].apply(data, args); + } else { + value = data[property]; + } + } + }); + + if(value!=undefined) { + return value; + } else { + return chain; + } + }; + + $.fn.selectpicker.defaults = { + style: null, + size: 'auto', + title: null, + selectedTextFormat : 'values', + noneSelectedText : 'Nothing selected', + width: null, + menuStyle: null, + toggleSize: null + } + +}(window.jQuery); diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap.min.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/chartist.min.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/chartist.min.js new file mode 100644 index 0000000..b69e484 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/chartist.min.js @@ -0,0 +1,9 @@ +/* Chartist.js 0.9.4 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ + +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.Chartist=b()}):"object"==typeof exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.9.4"};return function(a,b,c){"use strict";c.noop=function(a){return a},c.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},c.extend=function(a){a=a||{};var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){for(var d in b)"object"!=typeof b[d]||null===b[d]||b[d]instanceof Array?a[d]=b[d]:a[d]=c.extend({},a[d],b[d])}),a},c.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},c.stripUnit=function(a){return"string"==typeof a&&(a=a.replace(/[^0-9\+-\.]/g,"")),+a},c.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},c.querySelector=function(a){return a instanceof Node?a:b.querySelector(a)},c.times=function(a){return Array.apply(null,new Array(a))},c.sum=function(a,b){return a+(b?b:0)},c.mapMultiply=function(a){return function(b){return b*a}},c.mapAdd=function(a){return function(b){return b+a}},c.serialMap=function(a,b){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return c.times(e).forEach(function(c,e){var f=a.map(function(a){return a[e]});d[e]=b.apply(null,f)}),d},c.roundWithPrecision=function(a,b){var d=Math.pow(10,b||c.precision);return Math.round(a*d)/d},c.precision=8,c.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},c.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,b,c.escapingMap[b])},a))},c.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,c.escapingMap[b],b)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(b){}return a},c.createSvg=function(a,b,d,e){var f;return b=b||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS("http://www.w3.org/2000/xmlns/",c.xmlNs.prefix)}).forEach(function(b){a.removeChild(b)}),f=new c.Svg("svg").attr({width:b,height:d}).addClass(e).attr({style:"width: "+b+"; height: "+d+";"}),a.appendChild(f._node),f},c.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;bf.high&&(f.high=c),h&&ck,m=e?c.rho(j.range):0;if(e&&c.projectLength(a,1,j)>=d)j.step=1;else if(e&&m=d)j.step=m;else for(;;){if(l&&c.projectLength(a,j.step,j)<=d)j.step*=2;else{if(l||!(c.projectLength(a,j.step/2,j)>=d))break;if(j.step/=2,e&&j.step%1!==0){j.step*=2;break}}if(i++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}for(g=j.min,h=j.max;g+j.step<=j.low;)g+=j.step;for(;h-j.step>=j.high;)h-=j.step;for(j.min=g,j.max=h,j.range=j.max-j.min,j.values=[],f=j.min;f<=j.max;f+=j.step)j.values.push(c.roundWithPrecision(f));return j},c.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},c.createChartRect=function(a,b,d){var e=!(!b.axisX&&!b.axisY),f=e?b.axisY.offset:0,g=e?b.axisX.offset:0,h=a.width()||c.stripUnit(b.width)||0,i=a.height()||c.stripUnit(b.height)||0,j=c.normalizePadding(b.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===b.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===b.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},c.createGrid=function(a,b,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",c.extend({type:"grid",axis:d,index:b,group:g,element:k},j))},c.createLabel=function(a,b,d,e,f,g,h,i,j,k,l){var m,n={};if(n[f.units.pos]=a+h[f.units.pos],n[f.counterUnits.pos]=h[f.counterUnits.pos],n[f.units.len]=b,n[f.counterUnits.len]=g-10,k){var o=''+e[d]+"";m=i.foreignObject(o,c.extend({style:"overflow: visible;"},n))}else m=i.elem("text",n,j.join(" ")).text(e[d]);l.emit("draw",c.extend({type:"label",axis:f,index:d,group:i,element:m,text:e[d]},n))},c.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},c.optionsProvider=function(b,d,e){function f(b){var f=h;if(h=c.extend({},j),d)for(i=0;i1){var i=[];return h.forEach(function(a){i.push(g(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(i)}if(a=h[0].pathCoordinates,d=h[0].valueData,a.length<=4)return c.Interpolation.none()(a,d);for(var j,k=(new c.Svg.Path).move(a[0],a[1],!1,d[0]),l=0,m=a.length;m-2*!j>l;l+=2){var n=[{x:+a[l-2],y:+a[l-1]},{x:+a[l],y:+a[l+1]},{x:+a[l+2],y:+a[l+3]},{x:+a[l+4],y:+a[l+5]}];j?l?m-4===l?n[3]={x:+a[0],y:+a[1]}:m-2===l&&(n[2]={x:+a[0],y:+a[1]},n[3]={x:+a[2],y:+a[3]}):n[0]={x:+a[m-2],y:+a[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+a[l],y:+a[l+1]}),k.curve(e*(-n[0].x+6*n[1].x+n[2].x)/6+f*n[2].x,e*(-n[0].y+6*n[1].y+n[2].y)/6+f*n[2].y,e*(n[1].x+6*n[2].x-n[3].x)/6+f*n[2].x,e*(n[1].y+6*n[2].y-n[3].y)/6+f*n[2].y,n[2].x,n[2].y,!1,d[(l+2)/2])}return k}},c.Interpolation.step=function(a){var b={postpone:!0};return a=c.extend({},b,a),function(b,d){for(var e=new c.Svg.Path,f=!0,g=2;g1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(h){var k=i.elem("path",{d:h.stringify()},a.classNames.area,!0).attr({values:b.normalized[g]},c.xmlNs.uri);this.eventEmitter.emit("draw",{type:"area",values:b.normalized[g],path:h.clone(),series:f,seriesIndex:g,axisX:d,axisY:e,chartRect:j,index:g,group:i,element:k})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:e.bounds,chartRect:j,axisX:d,axisY:e,svg:this.svg,options:a})}function e(a,b,d,e){c.Line["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Line=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a){var b,d={raw:this.data,normalized:a.distributeSeries?c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y").map(function(a){return[a]}):c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y")};this.svg=c.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var e=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars){var i=c.serialMap(d.normalized,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+b.x||0,y:a.y+b.y||0}},{x:0,y:0})});b=c.getHighLow([i],c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y")}else b=c.getHighLow(d.normalized,c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y");b.high=+a.high||(0===a.high?0:b.high),b.low=+a.low||(0===a.low?0:b.low);var j,k,l,m,n,o=c.createChartRect(this.svg,a,f.padding);k=a.distributeSeries&&a.stackBars?d.raw.labels.slice(0,1):d.raw.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})):a.axisX.type.call(c,c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})),l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y,d,o,{ticks:k}):a.axisY.type.call(c,c.Axis.units.y,d,o,a.axisY)):(l=m=void 0===a.axisX.type?new c.StepAxis(c.Axis.units.x,d,o,{ticks:k}):a.axisX.type.call(c,c.Axis.units.x,d,o,a.axisX),j=n=void 0===a.axisY.type?new c.AutoScaleAxis(c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})):a.axisY.type.call(c,c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),d.raw.series.forEach(function(b,e){var f,h,i=e-(d.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/d.normalized.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/d.normalized[e].length/2,h=g.elem("g"),h.attr({"series-name":b.name,meta:c.serialize(b.meta)},c.xmlNs.uri),h.addClass([a.classNames.series,b.className||a.classNames.series+"-"+c.alphaNumerate(e)].join(" ")),d.normalized[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,d.normalized[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,d.normalized[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,d.normalized[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,d.normalized[e])},l instanceof c.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],v[l.counterUnits.pos+"1"]=a.stackBars?t:p,v[l.counterUnits.pos+"2"]=a.stackBars?q[k]:r[l.counterUnits.pos],v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1),s=h.elem("line",v,a.classNames.bar).attr({value:[g.x,g.y].filter(function(a){return a}).join(","),meta:c.getMetaData(b,k)},c.xmlNs.uri), +this.eventEmitter.emit("draw",c.extend({type:"bar",value:g,index:k,meta:c.getMetaData(b,k),series:b,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function e(a,b,d,e){c.Bar["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,onlyInteger:!1,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,horizontalBars:!1,distributeSeries:!1,reverseData:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Bar=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function e(a){var b,e,f,h,i,j=[],k=a.startAngle,l=c.getDataArray(this.data,a.reverseData);this.svg=c.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=c.createChartRect(this.svg,a,g.padding),f=Math.min(e.width()/2,e.height()/2),i=a.total||l.reduce(function(a,b){return a+b},0),f-=a.donut?a.donutWidth/2:0,h="outside"===a.labelPosition||a.donut?f:"center"===a.labelPosition?0:f/2,h+=a.labelOffset;var m={x:e.x1+e.width()/2,y:e.y2+e.height()/2},n=1===this.data.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;a.showLabel&&(b=this.svg.elem("g",null,null,!0));for(var o=0;o180,0,r.x,r.y);a.donut||t.line(m.x,m.y);var u=j[o].elem("path",{d:t.stringify()},a.donut?a.classNames.sliceDonut:a.classNames.slicePie);if(u.attr({value:l[o],meta:c.serialize(p.meta)},c.xmlNs.uri),a.donut&&u.attr({style:"stroke-width: "+ +a.donutWidth+"px"}),this.eventEmitter.emit("draw",{type:"slice",value:l[o],totalDataSum:i,index:o,meta:p.meta,series:p,group:j[o],element:u,path:t.clone(),center:m,radius:f,startAngle:k,endAngle:q}),a.showLabel){var v=c.polarToCartesian(m.x,m.y,h,k+(q-k)/2),w=a.labelInterpolationFnc(this.data.labels?this.data.labels[o]:l[o],o);if(w||0===w){var x=b.elem("text",{dx:v.x,dy:v.y,"text-anchor":d(m,v,a.labelDirection)},a.classNames.label).text(""+w);this.eventEmitter.emit("draw",{type:"label",index:o,group:b,element:x,text:""+w,x:v.x,y:v.y})}}k=q}this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function f(a,b,d,e){c.Pie["super"].constructor.call(this,a,b,g,c.extend({},g,d),e)}var g={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:c.noop,labelDirection:"neutral",reverseData:!1};c.Pie=c.Base.extend({constructor:f,createChart:e,determineAnchorPosition:d})}(window,document,a),a}); +//# sourceMappingURL=chartist.min.js.map \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/demo.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/demo.js new file mode 100644 index 0000000..b4bb5ee --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/demo.js @@ -0,0 +1,152 @@ +type = ['','info','success','warning','danger']; + + +demo = { + initPickColor: function(){ + $('.pick-class-label').click(function(){ + var new_class = $(this).attr('new-class'); + var old_class = $('#display-buttons').attr('data-class'); + var display_div = $('#display-buttons'); + if(display_div.length) { + var display_buttons = display_div.find('.btn'); + display_buttons.removeClass(old_class); + display_buttons.addClass(new_class); + display_div.attr('data-class', new_class); + } + }); + }, + + initChartist: function(){ + + var dataSales = { + labels: ['9:00AM', '12:00AM', '3:00PM', '6:00PM', '9:00PM', '12:00PM', '3:00AM', '6:00AM'], + series: [ + [287, 385, 490, 492, 554, 586, 698, 695, 752, 788, 846, 944], + [67, 152, 143, 240, 287, 335, 435, 437, 539, 542, 544, 647], + [23, 113, 67, 108, 190, 239, 307, 308, 439, 410, 410, 509] + ] + }; + + var optionsSales = { + lineSmooth: false, + low: 0, + high: 800, + showArea: true, + height: "245px", + axisX: { + showGrid: false, + }, + lineSmooth: Chartist.Interpolation.simple({ + divisor: 3 + }), + showLine: false, + showPoint: false, + }; + + var responsiveSales = [ + ['screen and (max-width: 640px)', { + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Line('#chartHours', dataSales, optionsSales, responsiveSales); + + + var data = { + labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + series: [ + [542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895], + [412, 243, 280, 580, 453, 353, 300, 364, 368, 410, 636, 695] + ] + }; + + var options = { + seriesBarDistance: 10, + axisX: { + showGrid: false + }, + height: "245px" + }; + + var responsiveOptions = [ + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Bar('#chartActivity', data, options, responsiveOptions); + + var dataPreferences = { + series: [ + [25, 30, 20, 25] + ] + }; + + var optionsPreferences = { + donut: true, + donutWidth: 40, + startAngle: 0, + total: 100, + showLabel: false, + axisX: { + showGrid: false + } + }; + + Chartist.Pie('#chartPreferences', dataPreferences, optionsPreferences); + + Chartist.Pie('#chartPreferences', { + labels: ['62%','32%','6%'], + series: [62, 32, 6] + }); + }, + + initGoogleMaps: function(){ + var myLatlng = new google.maps.LatLng(40.748817, -73.985428); + var mapOptions = { + zoom: 13, + center: myLatlng, + scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page + styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}] + + } + var map = new google.maps.Map(document.getElementById("map"), mapOptions); + + var marker = new google.maps.Marker({ + position: myLatlng, + title:"Hello World!" + }); + + // To add the marker to the map, call setMap(); + marker.setMap(map); + }, + + showNotification: function(from, align){ + color = Math.floor((Math.random() * 4) + 1); + + $.notify({ + icon: "pe-7s-gift", + message: "Welcome to Light Bootstrap Dashboard - a beautiful freebie for every web developer." + + },{ + type: type[color], + timer: 4000, + placement: { + from: from, + align: align + } + }); + } + + +} + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/jquery-1.10.2.js b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/jquery-1.10.2.js new file mode 100644 index 0000000..d6f6ac8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/html/assets/js/jquery-1.10.2.js @@ -0,0 +1,9789 @@ +/*! + * jQuery JavaScript Library v1.10.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:48Z + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<10 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.10.2", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( jQuery.support.ownLast ) { + for ( key in obj ) { + return core_hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.10.2 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
    "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + + var all, a, input, select, fragment, opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
    a"; + + // Finish early in limited (non-browser) environments + all = div.getElementsByTagName("*") || []; + a = div.getElementsByTagName("a")[ 0 ]; + if ( !a || !a.style || !all.length ) { + return support; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName("tbody").length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName("link").length; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + support.opacity = /^0.5/.test( a.style.opacity ); + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!a.style.cssFloat; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; + + // Will be defined later + support.inlineBlockNeedsLayout = false; + support.shrinkWrapBlocks = false; + support.pixelPosition = false; + support.deleteExpando = true; + support.noCloneEvent = true; + support.reliableMarginRight = true; + support.boxSizingReliable = true; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: IE<9 + // Iteration over object's inherited properties before its own. + for ( i in jQuery( support ) ) { + break; + } + support.ownLast = i !== "0"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior. + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
    "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})({}); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "applet": true, + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + data = null, + i = 0, + elem = this[0]; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( name.indexOf("data-") === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // Use proper attribute retrieval(#6932, #12072) + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + jQuery.expr.attrHandle[ name ] = fn; + return ret; + } : + function( elem, name, isXML ) { + return isXML ? + undefined : + elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = + // Some attributes are constructed with empty-string values when not defined + function( elem, name, isXML ) { + var ret; + return isXML ? + undefined : + (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + }; + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ret.specified ? + ret.value : + undefined; + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = ret.push( cur ); + break; + } + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
    ", "
    " ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + col: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
    ", "
    " ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
    " && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(" + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/donutchartssimple.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/README.md b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/dashboard.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/graphs.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/metricdescriptions.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/notifications.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/table.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/template.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartmethod.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartpackage.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartx.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/defaultclassmetrics.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/overview_metric_data.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..2706753 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-core", "Number of Highly Problematic Classes":0, "Number of Entities":29, "Number of Problematic Classes":4, "Class Lines of Code":2340, "Number of External Packages":9, "Number of Packages":5, "Number of External Entities":371} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/packagedependency.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..edfbc0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/packagedependency.js @@ -0,0 +1,17 @@ +var matrix = [[0,1,8,1,1],[0,0,2,2,0],[1,0,0,1,0],[3,3,3,0,0],[0,0,0,0,0]] +var packages = [{ +"name": " org.ugp.serialx.converters", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.protocols", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.utils", "color": " #9ecae1" +} +,{ +"name": " org.ugp.serialx", "color": " #c6dbef" +} +,{ +"name": " org.ugp.serialx.converters.imports", "color": " #e6550d" +} +]; diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/summary_data.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..3937ccb --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 1244,count:4}, +{label:"fair quality attributes", color: "#007F24", value: 1315,count:25}]; diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..67e8693 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,226 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-core", "value":2340, +"prmetrics":{"5":1,"6":1,"7":1,"8":2,"9":1,"10":1,"11":4}, +"prmetricvalues":{"5":0,"6":29,"7":4,"8":2340,"9":9,"10":5,"11":371}, +"children": [ { +"name": "org.ugp.serialx.converters", "value":571, +"pmetrics":{"4":3,"12":2,"13":1,"14":2,"3":1,"1":2,"0":2,"6":3,"8":2,"2":2,"15":1,"16":2}, +"pmetricvalues":{"4":3,"12":8,"13":2,"14":10,"3":1,"1":2,"0":2,"17":0.166,"6":12,"18":0.167,"8":571,"19":0.667,"2":2,"15":4,"16":288}, +"children":[ +{ +"name": "ProtocolConverter","key": "y","value":157, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, +"metricvalues":{"20":7,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":7,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +}, +{ +"name": "SerializableBase64Converter","key": "B","value":37, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +}, +{ +"name": "DataParser","key": "E","value":117, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +}, +{ +"name": "CharacterConverter","key": "G","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "NumberConverter","key": "x","value":88, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +}, +{ +"name": "VariableParser","key": "D","value":42, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":5,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":5,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} +}, +{ +"name": "StringConverter","key": "m","value":51, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +}, +{ +"name": "DataConverter","key": "P","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +}, +{ +"name": "BooleanConverter","key": "Q","value":29, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +}, +{ +"name": "NullConverter","key": "L","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +} +] +},{ +"name": "org.ugp.serialx.protocols", "value":223, +"pmetrics":{"4":2,"12":1,"13":1,"14":2,"3":1,"1":1,"0":1,"6":2,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":3,"13":0,"14":7,"3":1,"1":1,"0":1,"17":0.428,"6":7,"18":0.143,"8":223,"19":0.429,"2":1,"15":4,"16":80}, +"children":[ +{ +"name": "EnumProtocol","key": "N","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "ScopeProtocol","key": "A","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +}, +{ +"name": "MapProtocol","key": "r","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +}, +{ +"name": "SerializationProtocol","key": "t","value":120, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, +"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +}, +{ +"name": "StringProtocol","key": "C","value":33, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +}, +{ +"name": "ListProtocol","key": "K","value":16, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +} +] +},{ +"name": "org.ugp.serialx.utils", "value":491, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":3,"16":2}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":3,"3":1,"1":2,"0":2,"17":0.929,"6":3,"18":0.0,"8":491,"19":0.071,"2":1,"15":13,"16":246}, +"children":[ +{ +"name": "LogProvider","key": "I","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "Registry","key": "O","value":125, +"metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +}, +{ +"name": "Utils","key": "w","value":346, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":1,"28":3,"29":5,"30":1,"31":1,"32":4,"33":1,"34":2,"35":3,"36":1,"16":5,"37":1,"4":3,"8":3,"2":1,"3":4,"1":5}, +"metricvalues":{"20":5,"21":0,"38":13,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"39":4,"33":5,"34":85,"40":9,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} +} +] +},{ +"name": "org.ugp.serialx", "value":923, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":3,"13":1,"14":3,"3":1,"1":2,"0":2,"17":0.071,"6":4,"18":0.5,"8":923,"19":0.429,"2":1,"15":4,"16":405}, +"children":[ +{ +"name": "GenericScope","key": "M","value":333, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, +"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +}, +{ +"name": "Scope","key": "s","value":353, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":1,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":1,"3":4,"1":5}, +"metricvalues":{"20":5,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":5,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} +}, +{ +"name": "MultimediaSerializer","key": "k","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +}, +{ +"name": "Serializer","key": "J","value":212, +"metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, +"metricvalues":{"20":8,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":8,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +} +] +},{ +"name": "org.ugp.serialx.converters.imports", "value":132, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":0,"13":1,"14":2,"3":1,"1":1,"0":1,"17":0.667,"6":3,"18":0.333,"8":132,"19":0.0,"2":1,"15":1,"16":49}, +"children":[ +{ +"name": "Import","key": "H","value":48, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, +"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +}, +{ +"name": "ImportsProvider","key": "o","value":84, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/table_data.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..9a55a0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#4)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1Scope ▄ ▄ ▄ ▄35317517349022Utils ▄ ▄ ▄ ▄3461881161013GenericScope ▄ ▄ ▄ ▄33313814460314Serializer ▄ ▄ ▄ ▄212792153433';var EQ_Table5_Title = 'List of all classes (#29)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1Serializer ▄ ▄ ▄ ▄212very-highlow-mediumvery-highmedium-high2ProtocolConverter ▄ ▄ ▄ ▄157medium-highlow-mediummedium-highlow-medium3Scope ▄ ▄ ▄ ▄353very-highlowhighhigh4Utils ▄ ▄ ▄ ▄346very-highlowhighmedium-high5GenericScope ▄ ▄ ▄ ▄333very-highlowvery-highvery-high6Registry ▄ ▄ ▄ ▄125medium-highlowlow-mediumlow-medium7NumberConverter ▄ ▄ ▄ ▄88low-mediumlowlow-mediumlow-medium8StringConverter ▄ ▄ ▄ ▄51low-mediumlowlow-mediumlow-medium9VariableParser ▄ ▄ ▄ ▄42low-mediumlowlowlow10StringProtocol ▄ ▄ ▄ ▄33low-mediumlowlowlow11MapProtocol ▄ ▄ ▄ ▄25low-mediumlowlowlow12ScopeProtocol ▄ ▄ ▄ ▄17low-mediumlowlowlow13ListProtocol ▄ ▄ ▄ ▄16low-mediumlowlowlow14EnumProtocol ▄ ▄ ▄ ▄12low-mediumlowlowlow15SerializationProt... ▄ ▄ ▄ ▄120lowlowmedium-highlow-medium16DataParser ▄ ▄ ▄ ▄117lowlowlowlow-medium17ParserRegistry ▄ ▄ ▄ ▄110lowlowlowlow18ImportsProvider ▄ ▄ ▄ ▄84lowlowlowlow-medium19ProtocolRegistry ▄ ▄ ▄ ▄57lowlowlowlow20Imports ▄ ▄ ▄ ▄51lowlowlowlow21Import ▄ ▄ ▄ ▄48lowlowlow-mediumlow22SerializableBase6... ▄ ▄ ▄ ▄37lowlowlowlow23BooleanConverter ▄ ▄ ▄ ▄29lowlowlowlow24MultimediaSerializer ▄ ▄ ▄ ▄25lowlowmedium-highlow25CharacterConverter ▄ ▄ ▄ ▄20lowlowlowlow26LogProvider ▄ ▄ ▄ ▄20lowlowlowlow27NullConverter ▄ ▄ ▄ ▄17lowlowlowlow28DataConverter ▄ ▄ ▄ ▄13lowlowlowlow29IsSelectorScope ▄ ▄ ▄ ▄1lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/report.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/reportforprint.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/sunburst.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/treemap.html b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/main_report/index.html b/SerialX-core/codemr/serialx-core/html/main_report/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/main_report/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/workingsets.js b/SerialX-core/codemr/serialx-core/html/workingsets.js new file mode 100644 index 0000000..d87de2e --- /dev/null +++ b/SerialX-core/codemr/serialx-core/html/workingsets.js @@ -0,0 +1,3 @@ +var EQ_workingSetList = [ +{name: 'serialx-core', path:'serialx-core'} +]; diff --git a/SerialX-core/codemr/serialx-core/serialx-core.mdl b/SerialX-core/codemr/serialx-core/serialx-core.mdl new file mode 100644 index 0000000000000000000000000000000000000000..dfb6c997dab114560f67130cba6f95f234a68bae GIT binary patch literal 47867 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/serialx-core.qa b/SerialX-core/codemr/serialx-core/serialx-core.qa new file mode 100644 index 0000000..426e409 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/serialx-core.qa @@ -0,0 +1 @@ +{"metrics":{"Number of Highly Problematic Classes":0,"Number of Entities":29,"Number of Problematic Classes":4,"Class Lines of Code":2340,"Number of External Packages":9,"Number of Packages":5,"Number of External Entities":371},"distributions":{"Coupling":{"distribution":[0,29,2,0,0,0],"locDistribution":[0,2190,369,0,0,0]},"Lack of Cohesion":{"distribution":[0,20,4,3,2,2],"locDistribution":[0,701,312,302,699,545]},"Complexity":{"distribution":[0,17,8,2,0,4],"locDistribution":[0,749,284,282,0,1244]}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/serialx-core.ws b/SerialX-core/codemr/serialx-core/serialx-core.ws new file mode 100644 index 0000000..0843576 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/serialx-core.ws @@ -0,0 +1 @@ +{"serialx-core":{"name":"serialx-core","packages":{"org.ugp.serialx.converters":{"packageName":"org.ugp.serialx.converters","isAll":false,"classes":["Lorg/ugp/serialx/converters/ProtocolConverter;","Lorg/ugp/serialx/converters/SerializableBase64Converter;","Lorg/ugp/serialx/converters/DataParser;","Lorg/ugp/serialx/converters/DataParser$ParserRegistry;","Lorg/ugp/serialx/converters/CharacterConverter;","Lorg/ugp/serialx/converters/NumberConverter;","Lorg/ugp/serialx/converters/VariableParser;","Lorg/ugp/serialx/converters/ProtocolConverter$IsSelectorScope;","Lorg/ugp/serialx/converters/StringConverter;","Lorg/ugp/serialx/converters/DataConverter;","Lorg/ugp/serialx/converters/BooleanConverter;","Lorg/ugp/serialx/converters/NullConverter;"]},"org.ugp.serialx.protocols":{"packageName":"org.ugp.serialx.protocols","isAll":false,"classes":["Lorg/ugp/serialx/protocols/EnumProtocol;","Lorg/ugp/serialx/protocols/SerializationProtocol$ProtocolRegistry;","Lorg/ugp/serialx/protocols/ScopeProtocol;","Lorg/ugp/serialx/protocols/MapProtocol;","Lorg/ugp/serialx/protocols/SerializationProtocol;","Lorg/ugp/serialx/protocols/StringProtocol;","Lorg/ugp/serialx/protocols/ListProtocol;"]},"org.ugp.serialx.utils":{"packageName":"org.ugp.serialx.utils","isAll":false,"classes":["Lorg/ugp/serialx/utils/LogProvider;","Lorg/ugp/serialx/utils/Registry;","Lorg/ugp/serialx/utils/Utils;"]},"org.ugp.serialx":{"packageName":"org.ugp.serialx","isAll":false,"classes":["Lorg/ugp/serialx/GenericScope;","Lorg/ugp/serialx/Scope;","Lorg/ugp/serialx/MultimediaSerializer;","Lorg/ugp/serialx/Serializer;"]},"org.ugp.serialx.converters.imports":{"packageName":"org.ugp.serialx.converters.imports","isAll":false,"classes":["Lorg/ugp/serialx/converters/imports/Import;","Lorg/ugp/serialx/converters/imports/ImportsProvider;","Lorg/ugp/serialx/converters/imports/ImportsProvider$Imports;"]}}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/graphs/all_bymodularity.cmr b/SerialX-json/codemr/serialx-json/graphs/all_bymodularity.cmr new file mode 100644 index 0000000..eadc484 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/graphs/all_bymodularity.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":2},{"@type":"int","id":"#edges","v":1},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"l":{"x":50.0,"y":57.0},"n":{"x":270.0,"y":50.0}},"vList":[{"type":"l"},{"type":"n"}],"eList":[{"L":[{"s":"l","d":"n","k":53,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/graphs/all_bypackage.cmr b/SerialX-json/codemr/serialx-json/graphs/all_bypackage.cmr new file mode 100644 index 0000000..fb4fd50 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/graphs/all_bypackage.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":2},{"@type":"int","id":"#edges","v":1},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"l":{"x":50.0,"y":50.0},"n":{"x":867.0,"y":120.0}},"vList":[{"type":"l"},{"type":"n"}],"eList":[{"L":[{"s":"l","d":"n","k":53,"w":1}]}],"clusterMap":{"l":2,"n":1}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/graphs/all_byprojectmodule.cmr b/SerialX-json/codemr/serialx-json/graphs/all_byprojectmodule.cmr new file mode 100644 index 0000000..8076256 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/graphs/all_byprojectmodule.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":2},{"@type":"int","id":"#edges","v":1},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"l":{"x":50.0,"y":77.0},"n":{"x":147.0,"y":50.0}},"vList":[{"type":"l"},{"type":"n"}],"eList":[{"L":[{"s":"l","d":"n","k":53,"w":1}]}],"clusterMap":{"l":1,"n":1}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/graphs/all_nm.cmr b/SerialX-json/codemr/serialx-json/graphs/all_nm.cmr new file mode 100644 index 0000000..66a1c04 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/graphs/all_nm.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":2},{"@type":"int","id":"#edges","v":1},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"l":{"x":50.0,"y":57.0},"n":{"x":270.0,"y":50.0}},"vList":[{"type":"l"},{"type":"n"}],"eList":[{"L":[{"s":"l","d":"n","k":53,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.html b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.html new file mode 100644 index 0000000..d8f7464 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.png b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bymodularity.png new file mode 100644 index 0000000000000000000000000000000000000000..938e4c5a41c665e8a50f0b8ce4dc20228f8f3e88 GIT binary patch literal 1694 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xs4kn<8()EGdS@(6mp$ZU`y8SuR(hPN**7Y8}!1fW##lB@7GRU5o`-5 z?_4q2=j0Nl@wRvwvgy^&sm~v_);zD>|9S4_pHKZy zEX-ASec=n+1;qpoVS^Sw;62qJh1*vYkJ?CGy5~m6P#zvRDBTs?bFQfZ?0u?7@y{o`EaeGH|9AMM z;>YRhb@o-~?`<u>0;{RF2#md(8&EK)1G%a(_ zM#H+I)RHILqd#*Wes(Qi?%tl~>5seX<=#o^x$UpY*i`xFNXq9opDK!r{~E_ve0#jT zr>>^r&zH-)&;R~Cf8XBCAEy0flsf=kV#P&+b3t%Vhok z$G2x0L3j1#X5`G9H9tph&b%1=52w%0|5Hg$zw>>~Py5H^<#&Jn=9jPi zwD0BbO?vbHo|x)>f1CZSy{84zmdPkQct7vgi?_$~cGSK*_J3`%`JaT3#h1UE?%h%K zk5G8;uS>i~oqr#Xu jcr;8#!vwiV|E9k&P4Z6Uj~fet^$vrltDnm{r-UW|rB$eU literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.html b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.html new file mode 100644 index 0000000..c213fff --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.png b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_bypackage.png new file mode 100644 index 0000000000000000000000000000000000000000..518f00d2d8cbd675aa0ca19bea2a938741b8feaa GIT binary patch literal 2313 zcmeH}>r;{m6vl-t%|>l@o4lp&R_<(i5h{)DxUciXt#SpQvL?8rY@B+NDIJ5h?f1sIjzC82HoO6E9ms5HA z6w=wr)5*@x&iO>tu{b+B*x}W7gxi!O^MR0^o#X2h$9_CZOw&y8tIrX<2l6Zqt#c_J z!MD5$rXwHjN>xS@zVn}uy!4dSExkVOmO9&iIp$_18})tlaZjgabW^~H?!d=FqK`Y8 zSX*~hAoIA>5=Y`94%a5TyYCF}oiPp#e)up^Ea5D#2o5PGv4_49(|BtRyTFbHe6F6a zb(p~OwMbGfr#o;7u6y~zfvKj-&OI)r?_(=~u>X{rMUvt%B4UxAO6CR>WaxsY22tnx zFyO*U{-VKeipB|?mrcfq+EJojW?Qd#Uzv8D550V?r9$W{5GOO-Dtd_*^D{#w4dL-C z3}ls{ht+ck-}5PCSHk`_(D;slD0!6B&63fzVksq+Y}Ufaui)^;zq@sYraiLtU0HiH z=7p*HIjXm3&i<@VEiJ5$4padthgr}33!40Jk)Vu2(3oD_0HS9uX@lbu6`9_}o}@t; zv&)+4VF&qQ6icZLq(~u$A%Km^G`v&$Dd&dn298LX`@ymo+xQFuyRwoObYXq+;XYD{ z70H#E`Em^;ZqS4jbM=aC5gsLSOnf9E>9-n>G_eX>TeD5`sxh$d%$sS*E|39v4^sXFJ57>7o(Qc^`U4hmx^C2Oo+j#LKlB&Il6Q21 zuwJF6D3@Rrb4wNqiTA-U zgKBGk*|CwoiGEDLY0x}-7DMBbq&GEm34!N8aDfg;vT6D>jOpXwQQI~Shj zNlB-I(h8Rv*}^kEG>}LYx9I~%?M9aMwTeqTp#96HDqz6<~{ALx0@$8DRK&?LMfV{E*A;;C_re*#0 ztA#Q4Bi5vD3&oYi->2!A?o>6sFUl23vA=_l<^CzV@AO!_!)_tBq8p!#Yww8Ja@$Vo zuSzo>v`f`)XQLPVjHGNFBg@!Huh@>>+`xj9@3&S{DJW6S>pbGT8p2T4Q zlWCLq<#~Efg0>~X-3%-vh$a58JFQ-bq)a1ESmc&1GtG2@YJm`AG%!{~IGHXAx=2y4 z8;#MC4O~{Jsg4wD!RpGp?MH&z5XF=<+#;?FY&BO?_j`qm6;DITRI^r&O8$kVtba&` zE?a4?)j;;jx4Y5zC@i=y^@h%beRH?1*p{~M^=@c*qlO~GI;Xpc2QZDFP@J3c>IG7( zy+!^ay^-X&!F?t;_?&OLjAj&4Dw8Z9U>~(b| zeVpMba;g9mOv+P)AJB8yv6}+yzy4BR2z(*%IRa+ixVMtNpO;d0+Fl&H6UR>-qZ~p1 F`Y&W9f*b$< literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.html b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.html new file mode 100644 index 0000000..c5c0502 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.png b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_byprojectmodule.png new file mode 100644 index 0000000000000000000000000000000000000000..69fb81b983f0d835c31148ffa0894769c71c84e2 GIT binary patch literal 1517 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xs4kn<8(}YiLnZ&1(moDU_l4Nkhz=NfEy23#PC83X(y1nx>F<}>nte-~Z(eec2F@;u-Fo75Fw z`)PV;!@SQTAN1Yb`k$uHi{ABTRr2=xhJW7uzN~+JE>Ktc_D)8Aw$<*_!un;S>;5f0 z$S&U($5U^&;m?=N+25tly#FDQIOD^7b{m_TiZ3!X+je|lbV@ z_L2RNu;bH{dDhe0_xr`o$-MLS)avzX_x!x}R_Vo)vEunPZukFe{Qm5u{NevsuQ1wg z`@K!pdi%Z21#cHVl|Po>#?Ie2uX+1@$vxkWec17T`-aM8+&^|N-Yplk=i$1!)9>2W z{}kT6ou6OU%61#~eBV0uoUWHlb+2CUe*SE|46BXRcm0_EXD9lr?PoB%D8i_}R%Xxp z%dd}p?Q{Qe@qGTwKO8q)f?58&`rd!$Z2U&C4=-%?R6IU6KYr#Pz8g9~i4*H)KeO9a zlvnrq*3FL>uO0uMGan+ub4Cgl{c6}##i%f5P8ki8(J%oOog3^K7ia2JaN5dL0E=-3 MPgg&ebxsLQ08t$-RR910 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.html b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.html new file mode 100644 index 0000000..d8f7464 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.png b/SerialX-json/codemr/serialx-json/html/graph_htmls/all_nm.png new file mode 100644 index 0000000000000000000000000000000000000000..938e4c5a41c665e8a50f0b8ce4dc20228f8f3e88 GIT binary patch literal 1694 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xs4kn<8()EGdS@(6mp$ZU`y8SuR(hPN**7Y8}!1fW##lB@7GRU5o`-5 z?_4q2=j0Nl@wRvwvgy^&sm~v_);zD>|9S4_pHKZy zEX-ASec=n+1;qpoVS^Sw;62qJh1*vYkJ?CGy5~m6P#zvRDBTs?bFQfZ?0u?7@y{o`EaeGH|9AMM z;>YRhb@o-~?`<u>0;{RF2#md(8&EK)1G%a(_ zM#H+I)RHILqd#*Wes(Qi?%tl~>5seX<=#o^x$UpY*i`xFNXq9opDK!r{~E_ve0#jT zr>>^r&zH-)&;R~Cf8XBCAEy0flsf=kV#P&+b3t%Vhok z$G2x0L3j1#X5`G9H9tph&b%1=52w%0|5Hg$zw>>~Py5H^<#&Jn=9jPi zwD0BbO?vbHo|x)>f1CZSy{84zmdPkQct7vgi?_$~cGSK*_J3`%`JaT3#h1UE?%h%K zk5G8;uS>i~oqr#Xu jcr;8#!vwiV|E9k&P4Z6Uj~fet^$vrltDnm{r-UW|rB$eU literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/graph_htmls/graphlist.js b/SerialX-json/codemr/serialx-json/html/graph_htmls/graphlist.js new file mode 100644 index 0000000..77dd55e --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/graph_htmls/graphlist.js @@ -0,0 +1 @@ +var EQ_graphHTMLText = '
    '; \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/Xdonut.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/Xdonut.html new file mode 100644 index 0000000..ab4d736 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/Xdonut.html @@ -0,0 +1,107 @@ + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/circlepack.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/circlepack.html new file mode 100644 index 0000000..1c6adf1 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/circlepack.html @@ -0,0 +1,113 @@ + + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + +
    +
    + + + + + +
    +
    +
    +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/dependency.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/dependency.html new file mode 100644 index 0000000..05b4312 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/dependency.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donut.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donut.html new file mode 100644 index 0000000..8ac1af3 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donut.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutcharts.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutcharts.html new file mode 100644 index 0000000..cc9471b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutcharts.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutchartssimple.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/README.md b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/dashboard.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/graphs.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/metricdescriptions.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/notifications.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/table.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/template.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartmethod.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartpackage.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartx.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/defaultclassmetrics.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/overview_metric_data.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..118d3d3 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-json working set: {serialx-json}", "Number of Highly Problematic Classes":0, "Number of Entities":5, "Number of Problematic Classes":1, "Class Lines of Code":153, "Number of External Packages":10, "Number of Packages":2, "Number of External Entities":29} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/packagedependency.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..f3e9b40 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/packagedependency.js @@ -0,0 +1,8 @@ +var matrix = [[0,0],[1,0]] +var packages = [{ +"name": " org.ugp.serialx.json", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.json.converters", "color": " #6baed6" +} +]; diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/summary_data.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..b72461b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 0,count:0}, +{label:"fair quality attributes", color: "#007F24", value: 153,count:5}]; diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/sunburst_data.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..531d094 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,108 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-json working set: {serialx-json}", "value":153, +"prmetrics":{"5":1,"6":1,"7":1,"8":1,"9":1,"10":1,"11":1}, +"prmetricvalues":{"5":0,"6":5,"7":1,"8":153,"9":10,"10":2,"11":29}, +"children": [ { +"name": "org.ugp.serialx.json", "value":95, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":1,"13":0,"14":1,"3":1,"1":1,"0":1,"17":0.5,"6":1,"18":0.0,"8":95,"19":0.5,"2":1,"15":1,"16":52}, +"children":[ +{ +"name": "JsonSerializer","key": "n","value":95, +"metrics":{"20":2,"21":1,"22":1,"23":5,"24":2,"25":1,"26":3,"0":4,"27":1,"28":2,"29":5,"30":5,"31":1,"32":4,"33":1,"34":1,"35":1,"36":2,"16":3,"37":1,"4":2,"8":2,"2":2,"3":4,"1":3}, +"metricvalues":{"20":8,"21":1,"38":1,"22":0,"23":1.667,"24":90,"25":0,"26":5,"0":4,"27":15,"28":54,"29":0.993,"30":1.111,"31":3,"32":0.839,"39":0,"33":0,"34":38,"40":1,"35":4,"36":8,"16":52,"37":5,"4":2,"8":95,"2":2,"3":4,"1":3} +} +] +},{ +"name": "org.ugp.serialx.json.converters", "value":58, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":4,"13":0,"14":4,"3":1,"1":1,"0":1,"17":0.0,"6":4,"18":0.0,"8":58,"19":1.0,"2":1,"15":0,"16":25}, +"children":[ +{ +"name": "JsonVariableConverter","key": "k","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":11,"25":0,"26":3,"0":2,"27":1,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":6,"35":0,"36":2,"16":5,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "JsonNumberConverter","key": "p","value":6, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":5,"25":0,"26":2,"0":2,"27":1,"28":3,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":2,"35":0,"36":2,"16":2,"37":0,"4":1,"8":6,"2":1,"3":1,"1":2} +}, +{ +"name": "JsonObjectConverter","key": "l","value":27, +"metrics":{"20":2,"21":1,"22":1,"23":5,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":1,"37":1,"4":1,"8":1,"2":2,"3":1,"1":2}, +"metricvalues":{"20":8,"21":0,"38":1,"22":0,"23":1.5,"24":26,"25":0,"26":3,"0":2,"27":2,"28":14,"29":0.0,"30":0.0,"31":0,"32":0.375,"39":1,"33":1,"34":12,"40":0,"35":0,"36":7,"16":12,"37":1,"4":1,"8":27,"2":2,"3":1,"1":2} +}, +{ +"name": "JsonCharacterConverter","key": "o","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":1,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":4,"28":6,"29":0.833,"30":0.0,"31":0,"32":0.55,"33":0,"34":4,"35":0,"36":2,"16":6,"37":0,"4":1,"8":13,"2":1,"3":1,"1":2} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/table_data.js b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..d311b2e --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#0)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT';var EQ_Table5_Title = 'List of all classes (#5)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1JsonSerializer ▄ ▄ ▄ ▄95medium-highlow-mediumhighlow-medium2JsonObjectConverter ▄ ▄ ▄ ▄27low-mediumlow-mediumlowlow3JsonCharacterConv... ▄ ▄ ▄ ▄13low-mediumlowlowlow4JsonVariableConve... ▄ ▄ ▄ ▄12low-mediumlowlowlow5JsonNumberConverter ▄ ▄ ▄ ▄6low-mediumlowlowlow'; \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/report.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/reportforprint.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/sunburst.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/treemap.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/index.html b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/html_report_serialx-json/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/animate.min.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/animate.min.css new file mode 100644 index 0000000..0b6a47d --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/animate.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license - http://opensource.org/licenses/MIT + +Copyright (c) 2015 Daniel Eden +*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}@keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}100%{opacity:1}}@keyframes fadeIn{from{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}100%{opacity:0}}@keyframes fadeOut{from{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/bootstrap.min.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/bootstrap.min.css new file mode 100644 index 0000000..d65c66b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;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:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;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,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/demo.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/demo.css new file mode 100644 index 0000000..febe628 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/demo.css @@ -0,0 +1,61 @@ +@media (min-width: 992px){ + .typo-line{ + padding-left: 140px; + margin-bottom: 40px; + position: relative; + } + + .typo-line .category{ + transform: translateY(-50%); + top: 50%; + left: 0px; + position: absolute; + } +} + +.all-icons [class*="pe-"]{ + font-size: 40px; +} +.all-icons input{ + border: 0; +} +.all-icons .font-icon-detail{ + text-align: center; + padding: 45px 0px 30px; + border: 1px solid #e5e5e5; + border-radius: 6px; + margin: 15px 0; +} +.all-icons .font-icon-detail input{ + margin: 25px auto 0; + width: 100%; + text-align: center; + display: block; + color: #aaa; + font-size: 13px; +} + +#map{ + position:relative; + width:100%; + height: calc(100% - 60px); +} + +.places-buttons .btn{ + margin-bottom: 30px +} +.sidebar .nav > li.active-pro{ + position: absolute; + width: 100%; + bottom: 10px; +} +.sidebar .nav > li.active-pro a{ + background: rgba(255, 255, 255, 0.14); + opacity: 1; + color: #FFFFFF; +} + +.table-upgrade td:nth-child(2), +.table-upgrade td:nth-child(3){ + text-align: center; +} diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/font-awesome.min.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/helptip.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/helptip.css new file mode 100644 index 0000000..8cca39a --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/helptip.css @@ -0,0 +1,148 @@ + +/*------------------------- + Inline help tip +--------------------------*/ + +.help-tip{ + position: relative; + top: 4px; + left: 0px; + text-align: center; + border-radius: 10%; + width: 48px; + height: 24px; + font-size: 14px; + line-height: 26px; + cursor: default; +} + + +.help-tip:before{ + content: url(../img/help.png); + font-weight: bold; + color:#fff; +} + +.help-tip:hover div{ + display:block; + transform-origin: 100% 0%; + + -webkit-animation: fadeIn 0.3s ease-in-out; + animation: fadeIn 0.3s ease-in-out; + +} + +.help-tip div{ + display: none; + text-align: left; + background-color: white; + padding: 20px; + width: 300px; + position: absolute; + border-radius: 3px; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + left: -100px; + color: black; + font-size: 13px; + line-height: 1.4; +} + +/* arrow */ +.help-tip div:before{ + position: absolute; + content: ''; + width:0; + height: 0; + border:6px solid transparent; + border-bottom-color: white; + left:100px; + top:-12px; + +} + +.help-tip div:after{ + width:100%; + height:40px; + content:''; + position: absolute; + top:-40px; + left:0; +} + + +@-webkit-keyframes fadeIn { + 0% { + opacity:0; + transform: scale(0.6); + } + + 100% { + opacity:100%; + transform: scale(1); + } +} + +@keyframes fadeIn { + 0% { opacity:0; } + 100% { opacity:100%; } +} + + + +@media (max-width: 1024px) { + #bsaHolder, footer{ display:none;} +} + + .tip-legend .legend-title { + text-align: left; + margin-bottom: 5px; + font-weight: bold; + font-size: 90%; + } + .tip-legend ul { + margin: 0; + margin-bottom: 5px; + padding: 0; + float: left; + list-style: none; + } + .tip-legend ul li { + font-size: 80%; + list-style: lower-roman; + margin-left:25px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li { + + font-size: 80%; + list-style: none; + margin-left: 0px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li span { + + float: left; + height: 16px; + width: 30px; + margin-right: 5px; + margin-left:0px; + border: 1px solid #999; + } + .tip-legend .tip-metric-source { + font-size: 90%; + color: #999; + clear: both; + } + .tip-legend a { + color: #777; + } + + .tip-subsection { + text-align: left; + margin-bottom: 5px; + font-size: 90%; + } \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/light-bootstrap-dashboard.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/light-bootstrap-dashboard.css new file mode 100644 index 0000000..3ce28f5 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/light-bootstrap-dashboard.css @@ -0,0 +1,3393 @@ +/* light colors */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } +} +@-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(360deg); + } +} +@-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + } +} +/* Font Smoothing */ +body, +h1, .h1, +h2, .h2, +h3, .h3, +h4, .h4, +h5, .h5, +h6, .h6, +p, +.navbar, +.brand, +.btn-simple, +.alert, +a, +.td-name, +td, +button.close { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-family: "Roboto","Helvetica Neue",Arial,sans-serif; + font-weight: 400; +} + +h1, .h1, h2, .h2, h3, .h3, h4, .h4 { + font-weight: 300; + margin: 30px 0 15px; +} + +h1, .h1 { + font-size: 52px; +} + +h2, .h2 { + font-size: 36px; +} + +h3, .h3 { + font-size: 28px; + margin: 20px 0 10px; +} + +h4, .h4 { + font-size: 22px; + line-height: 30px; +} + +h5, .h5 { + font-size: 16px; + margin-bottom: 15px; +} + +h6, .h6 { + font-size: 14px; + font-weight: 600; + text-transform: uppercase; +} + +p { + font-size: 16px; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #9A9A9A; + font-weight: 300; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 60%; +} + +h1 .subtitle { + display: block; + margin: 0 0 30px; +} + +.text-muted { + color: #9A9A9A; +} + +.text-primary, .text-primary:hover { + color: #1D62F0 !important; +} + +.text-info, .text-info:hover { + color: #1DC7EA !important; +} + +.text-success, .text-success:hover { + color: #87CB16 !important; +} + +.text-warning, .text-warning:hover { + color: #FF9500 !important; +} + +.text-danger, .text-danger:hover { + color: #FF4A55 !important; +} + +/* General overwrite */ +body, +.wrapper { + min-height: 100vh; + position: relative; +} + +a { + color: #1DC7EA; +} +a:hover, a:focus { + color: #42d0ed; + text-decoration: none; +} + +a:focus, a:active, +button::-moz-focus-inner, +input::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +select::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + outline: 0; +} + +.ui-slider-handle:focus, +.navbar-toggle, +input:focus { + outline: 0 !important; +} + +/* Animations */ +.form-control, +.input-group-addon, +.tagsinput, +.navbar, +.navbar .alert { + -webkit-transition: all 300ms linear; + -moz-transition: all 300ms linear; + -o-transition: all 300ms linear; + -ms-transition: all 300ms linear; + transition: all 300ms linear; +} + +.sidebar .nav a, +.table > tbody > tr .td-actions .btn { + -webkit-transition: all 150ms ease-in; + -moz-transition: all 150ms ease-in; + -o-transition: all 150ms ease-in; + -ms-transition: all 150ms ease-in; + transition: all 150ms ease-in; +} + +.btn { + -webkit-transition: all 100ms ease-in; + -moz-transition: all 100ms ease-in; + -o-transition: all 100ms ease-in; + -ms-transition: all 100ms ease-in; + transition: all 100ms ease-in; +} + +.fa { + width: 18px; + text-align: center; +} + +.margin-top { + margin-top: 50px; +} + +.wrapper { + position: relative; + top: 0; + height: 100vh; +} + +.sidebar { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 260px; + display: block; + z-index: 1; + color: #fff; + font-weight: 200; + background-size: cover; + background-position: center center; +} +.sidebar .sidebar-wrapper { + position: relative; + max-height: none; + min-height: 100%; + overflow: hidden; + width: 260px; + z-index: 4; +} +.sidebar .sidebar-background { + position: absolute; + z-index: 1; + height: 100%; + width: 100%; + display: block; + top: 0; + left: 0; + background-size: cover; + background-position: center center; +} +.sidebar .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar .nav { + margin-top: 20px; +} +.sidebar .nav li > a { + color: #FFFFFF; + margin: 5px 15px; + opacity: .86; + border-radius: 4px; +} +.sidebar .nav li:hover > a { + background: rgba(255, 255, 255, 0.13); + opacity: 1; +} +.sidebar .nav li.active > a { + color: #FFFFFF; + opacity: 1; + background: rgba(255, 255, 255, 0.23); +} +.sidebar .nav p { + margin: 0; + line-height: 30px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.sidebar .nav i { + font-size: 28px; + float: left; + margin-right: 15px; + line-height: 30px; + width: 30px; + text-align: center; +} + +.sidebar .logo, +body > .navbar-collapse .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p, +body > .navbar-collapse .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text, +body > .navbar-collapse .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim, +body > .navbar-collapse .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img, +body > .navbar-collapse .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar:after, .sidebar:before, +body > .navbar-collapse:after, +body > .navbar-collapse:before { + display: block; + content: ""; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +.sidebar:before, +body > .navbar-collapse:before { + opacity: .33; + background: #000000; +} +.sidebar:after, +body > .navbar-collapse:after { + background: #787878; + background: -moz-linear-gradient(top, #787878 0%, #343434 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #787878), color-stop(100%, #343434)); + background: -webkit-linear-gradient(top, #787878 0%, #343434 100%); + background: -o-linear-gradient(top, #787878 0%, #343434 100%); + background: -ms-linear-gradient(top, #787878 0%, #343434 100%); + background: linear-gradient(to bottom, #787878 0%, #343434 100%); + background-size: 150% 150%; + z-index: 3; + opacity: 1; +} +.sidebar[data-image]:after, .sidebar.has-image:after, +body > .navbar-collapse[data-image]:after, +body > .navbar-collapse.has-image:after { + opacity: .77; +} +.sidebar[data-color="blue"]:after, +body > .navbar-collapse[data-color="blue"]:after { + background: #1F77D0; + background: -moz-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1F77D0), color-stop(100%, #533ce1)); + background: -webkit-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -o-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -ms-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: linear-gradient(to bottom, #1F77D0 0%, #533ce1 100%); + background-size: 150% 150%; +} +.sidebar[data-color="azure"]:after, +body > .navbar-collapse[data-color="azure"]:after { + background: #1DC7EA; + background: -moz-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1DC7EA), color-stop(100%, #4091ff)); + background: -webkit-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -o-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -ms-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: linear-gradient(to bottom, #1DC7EA 0%, #4091ff 100%); + background-size: 150% 150%; +} +.sidebar[data-color="green"]:after, +body > .navbar-collapse[data-color="green"]:after { + background: #87CB16; + background: -moz-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #87CB16), color-stop(100%, #6dc030)); + background: -webkit-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -o-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -ms-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: linear-gradient(to bottom, #87CB16 0%, #6dc030 100%); + background-size: 150% 150%; +} +.sidebar[data-color="orange"]:after, +body > .navbar-collapse[data-color="orange"]:after { + background: #FFA534; + background: -moz-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FFA534), color-stop(100%, #ff5221)); + background: -webkit-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -o-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -ms-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: linear-gradient(to bottom, #FFA534 0%, #ff5221 100%); + background-size: 150% 150%; +} +.sidebar[data-color="red"]:after, +body > .navbar-collapse[data-color="red"]:after { + background: #FB404B; + background: -moz-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FB404B), color-stop(100%, #bb0502)); + background: -webkit-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -o-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -ms-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: linear-gradient(to bottom, #FB404B 0%, #bb0502 100%); + background-size: 150% 150%; +} +.sidebar[data-color="purple"]:after, +body > .navbar-collapse[data-color="purple"]:after { + background: #9368E9; + background: -moz-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9368E9), color-stop(100%, #943bea)); + background: -webkit-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -o-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -ms-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: linear-gradient(to bottom, #9368E9 0%, #943bea 100%); + background-size: 150% 150%; +} + +.main-panel { + background: rgba(203, 203, 210, 0.15); + position: relative; + z-index: 2; + float: right; + width: calc(100% - 260px); + min-height: 100%; +} +.main-panel > .content { + padding: 30px 15px; + min-height: calc(100% - 123px); +} +.main-panel > .footer { + border-top: 1px solid #e7e7e7; +} +.main-panel .navbar { + margin-bottom: 0; +} + +.sidebar, +.main-panel { + overflow: auto; + max-height: 100%; + height: 100%; + -webkit-transition-property: top,bottom; + transition-property: top,bottom; + -webkit-transition-duration: .2s,.2s; + transition-duration: .2s,.2s; + -webkit-transition-timing-function: linear,linear; + transition-timing-function: linear,linear; + -webkit-overflow-scrolling: touch; +} + +.btn { + border-width: 2px; + background-color: transparent; + font-weight: 400; + opacity: 0.8; + filter: alpha(opacity=80); + padding: 8px 16px; + border-color: #888888; + color: #888888; +} +.btn:hover, .btn:focus, .btn:active, .btn.active, .open > .btn.dropdown-toggle { + background-color: transparent; + color: #777777; + border-color: #777777; +} +.btn.disabled, .btn.disabled:hover, .btn.disabled:focus, .btn.disabled.focus, .btn.disabled:active, .btn.disabled.active, .btn:disabled, .btn:disabled:hover, .btn:disabled:focus, .btn:disabled.focus, .btn:disabled:active, .btn:disabled.active, .btn[disabled], .btn[disabled]:hover, .btn[disabled]:focus, .btn[disabled].focus, .btn[disabled]:active, .btn[disabled].active, fieldset[disabled] .btn, fieldset[disabled] .btn:hover, fieldset[disabled] .btn:focus, fieldset[disabled] .btn.focus, fieldset[disabled] .btn:active, fieldset[disabled] .btn.active { + background-color: transparent; + border-color: #888888; +} +.btn.btn-fill { + color: #FFFFFF; + background-color: #888888; + opacity: 1; + filter: alpha(opacity=100); +} +.btn.btn-fill:hover, .btn.btn-fill:focus, .btn.btn-fill:active, .btn.btn-fill.active, .open > .btn.btn-fill.dropdown-toggle { + background-color: #777777; + color: #FFFFFF; +} +.btn.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn .caret { + border-top-color: #888888; +} +.btn:hover, .btn:focus { + opacity: 1; + filter: alpha(opacity=100); + outline: 0 !important; +} +.btn:active, .btn.active, .open > .btn.dropdown-toggle { + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; +} +.btn.btn-icon { + padding: 8px; +} + +.btn-primary { + border-color: #3472F7; + color: #3472F7; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { + background-color: transparent; + color: #1D62F0; + border-color: #1D62F0; +} +.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary:disabled, .btn-primary:disabled:hover, .btn-primary:disabled:focus, .btn-primary:disabled.focus, .btn-primary:disabled:active, .btn-primary:disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active { + background-color: transparent; + border-color: #3472F7; +} +.btn-primary.btn-fill { + color: #FFFFFF; + background-color: #3472F7; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary.btn-fill:hover, .btn-primary.btn-fill:focus, .btn-primary.btn-fill:active, .btn-primary.btn-fill.active, .open > .btn-primary.btn-fill.dropdown-toggle { + background-color: #1D62F0; + color: #FFFFFF; +} +.btn-primary.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-primary .caret { + border-top-color: #3472F7; +} + +.btn-success { + border-color: #87CB16; + color: #87CB16; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { + background-color: transparent; + color: #049F0C; + border-color: #049F0C; +} +.btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success:disabled, .btn-success:disabled:hover, .btn-success:disabled:focus, .btn-success:disabled.focus, .btn-success:disabled:active, .btn-success:disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled].active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active { + background-color: transparent; + border-color: #87CB16; +} +.btn-success.btn-fill { + color: #FFFFFF; + background-color: #87CB16; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-success.btn-fill:hover, .btn-success.btn-fill:focus, .btn-success.btn-fill:active, .btn-success.btn-fill.active, .open > .btn-success.btn-fill.dropdown-toggle { + background-color: #049F0C; + color: #FFFFFF; +} +.btn-success.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-success .caret { + border-top-color: #87CB16; +} + +.btn-info { + border-color: #1DC7EA; + color: #1DC7EA; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { + background-color: transparent; + color: #42d0ed; + border-color: #42d0ed; +} +.btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info:disabled, .btn-info:disabled:hover, .btn-info:disabled:focus, .btn-info:disabled.focus, .btn-info:disabled:active, .btn-info:disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled].active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active { + background-color: transparent; + border-color: #1DC7EA; +} +.btn-info.btn-fill { + color: #FFFFFF; + background-color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-info.btn-fill:hover, .btn-info.btn-fill:focus, .btn-info.btn-fill:active, .btn-info.btn-fill.active, .open > .btn-info.btn-fill.dropdown-toggle { + background-color: #42d0ed; + color: #FFFFFF; +} +.btn-info.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-info .caret { + border-top-color: #1DC7EA; +} + +.btn-warning { + border-color: #FF9500; + color: #FF9500; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + background-color: transparent; + color: #ED8D00; + border-color: #ED8D00; +} +.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning:disabled, .btn-warning:disabled:hover, .btn-warning:disabled:focus, .btn-warning:disabled.focus, .btn-warning:disabled:active, .btn-warning:disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active { + background-color: transparent; + border-color: #FF9500; +} +.btn-warning.btn-fill { + color: #FFFFFF; + background-color: #FF9500; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-warning.btn-fill:hover, .btn-warning.btn-fill:focus, .btn-warning.btn-fill:active, .btn-warning.btn-fill.active, .open > .btn-warning.btn-fill.dropdown-toggle { + background-color: #ED8D00; + color: #FFFFFF; +} +.btn-warning.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-warning .caret { + border-top-color: #FF9500; +} + +.btn-danger { + border-color: #FF4A55; + color: #FF4A55; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { + background-color: transparent; + color: #EE2D20; + border-color: #EE2D20; +} +.btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger:disabled, .btn-danger:disabled:hover, .btn-danger:disabled:focus, .btn-danger:disabled.focus, .btn-danger:disabled:active, .btn-danger:disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active { + background-color: transparent; + border-color: #FF4A55; +} +.btn-danger.btn-fill { + color: #FFFFFF; + background-color: #FF4A55; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-danger.btn-fill:hover, .btn-danger.btn-fill:focus, .btn-danger.btn-fill:active, .btn-danger.btn-fill.active, .open > .btn-danger.btn-fill.dropdown-toggle { + background-color: #EE2D20; + color: #FFFFFF; +} +.btn-danger.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-danger .caret { + border-top-color: #FF4A55; +} + +.btn-neutral { + border-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral:hover, .btn-neutral:focus, .btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: transparent; + color: #FFFFFF; + border-color: #FFFFFF; +} +.btn-neutral.disabled, .btn-neutral.disabled:hover, .btn-neutral.disabled:focus, .btn-neutral.disabled.focus, .btn-neutral.disabled:active, .btn-neutral.disabled.active, .btn-neutral:disabled, .btn-neutral:disabled:hover, .btn-neutral:disabled:focus, .btn-neutral:disabled.focus, .btn-neutral:disabled:active, .btn-neutral:disabled.active, .btn-neutral[disabled], .btn-neutral[disabled]:hover, .btn-neutral[disabled]:focus, .btn-neutral[disabled].focus, .btn-neutral[disabled]:active, .btn-neutral[disabled].active, fieldset[disabled] .btn-neutral, fieldset[disabled] .btn-neutral:hover, fieldset[disabled] .btn-neutral:focus, fieldset[disabled] .btn-neutral.focus, fieldset[disabled] .btn-neutral:active, fieldset[disabled] .btn-neutral.active { + background-color: transparent; + border-color: #FFFFFF; +} +.btn-neutral.btn-fill { + color: #FFFFFF; + background-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus, .btn-neutral.btn-fill:active, .btn-neutral.btn-fill.active, .open > .btn-neutral.btn-fill.dropdown-toggle { + background-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-neutral .caret { + border-top-color: #FFFFFF; +} +.btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: #FFFFFF; + color: #888888; +} +.btn-neutral.btn-fill, .btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus { + color: #888888; +} +.btn-neutral.btn-simple:active, .btn-neutral.btn-simple.active { + background-color: transparent; +} + +.btn:disabled, .btn[disabled], .btn.disabled { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.btn-round { + border-width: 1px; + border-radius: 30px !important; + padding: 9px 18px; +} +.btn-round.btn-icon { + padding: 9px; +} + +.btn-simple { + border: 0; + font-size: 16px; + padding: 8px 16px; +} +.btn-simple.btn-icon { + padding: 8px; +} + +.btn-lg { + font-size: 18px; + border-radius: 6px; + padding: 14px 30px; + font-weight: 400; +} +.btn-lg.btn-round { + padding: 15px 30px; +} +.btn-lg.btn-simple { + padding: 16px 30px; +} + +.btn-sm { + font-size: 12px; + border-radius: 3px; + padding: 5px 10px; +} +.btn-sm.btn-round { + padding: 6px 10px; +} +.btn-sm.btn-simple { + padding: 7px 10px; +} + +.btn-xs { + font-size: 12px; + border-radius: 3px; + padding: 1px 5px; +} +.btn-xs.btn-round { + padding: 2px 5px; +} +.btn-xs.btn-simple { + padding: 3px 5px; +} + +.btn-wd { + min-width: 140px; +} + +.btn-group.select { + width: 100%; +} + +.btn-group.select .btn { + text-align: left; +} + +.btn-group.select .caret { + position: absolute; + top: 50%; + margin-top: -1px; + right: 8px; +} + +.form-control::-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control::-webkit-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-ms-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; + color: #565656; + padding: 8px 12px; + height: 40px; + -webkit-box-shadow: none; + box-shadow: none; +} +.form-control:focus { + background-color: #FFFFFF; + border: 1px solid #AAAAAA; + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; + color: #333333; +} +.has-success .form-control, .has-error .form-control, .has-success .form-control:focus, .has-error .form-control:focus { + border-color: #E3E3E3; + -webkit-box-shadow: none; + box-shadow: none; +} +.has-success .form-control { + color: #87CB16; +} +.has-success .form-control:focus { + border-color: #87CB16; +} +.has-error .form-control { + color: #FF4A55; +} +.has-error .form-control:focus { + border-color: #FF4A55; +} +.form-control + .form-control-feedback { + border-radius: 6px; + font-size: 14px; + margin-top: -7px; + position: absolute; + right: 10px; + top: 50%; + vertical-align: middle; +} +.open .form-control { + border-radius: 4px 4px 0 0; + border-bottom-color: transparent; +} + +.input-lg { + height: 55px; + padding: 14px 30px; +} + +.has-error .form-control-feedback { + color: #FF4A55; +} + +.has-success .form-control-feedback { + color: #87CB16; +} + +.input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; +} +.has-success .input-group-addon, .has-error .input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; +} +.has-error .form-control:focus + .input-group-addon { + border-color: #FF4A55; + color: #FF4A55; +} +.has-success .form-control:focus + .input-group-addon { + border-color: #87CB16; + color: #87CB16; +} +.form-control:focus + .input-group-addon, .form-control:focus ~ .input-group-addon { + background-color: #FFFFFF; + border-color: #9A9A9A; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-right: 0 none; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-left: 0 none; +} + +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + background-color: #F5F5F5; + color: #888888; + cursor: not-allowed; +} + +.input-group-btn .btn { + border-width: 1px; + padding: 9px 16px; +} + +.input-group-btn .btn-default:not(.btn-fill) { + border-color: #DDDDDD; +} + +.input-group-btn:last-child > .btn { + margin-left: 0; +} + +.input-group-focus .input-group-addon { + border-color: #9A9A9A; +} + +.alert { + border: 0; + border-radius: 0; + color: #FFFFFF; + padding: 10px 15px; + font-size: 14px; +} +.container .alert { + border-radius: 4px; +} +.navbar .alert { + border-radius: 0; + left: 0; + position: absolute; + right: 0; + top: 85px; + width: 100%; + z-index: 3; +} +.navbar:not(.navbar-transparent) .alert { + top: 70px; +} +.alert span[data-notify="icon"] { + font-size: 30px; + display: block; + left: 15px; + position: absolute; + top: 50%; + margin-top: -15px; +} +.alert button.close { + position: absolute; + right: 10px; + top: 50%; + margin-top: -13px; + z-index: 1033; + background-color: #FFFFFF; + display: block; + border-radius: 50%; + opacity: .4; + line-height: 11px; + width: 25px; + height: 25px; + outline: 0 !important; + text-align: center; + padding: 3px; + font-weight: 300; +} +.alert button.close:hover { + opacity: .55; +} +.alert .close ~ span { + display: block; + max-width: 89%; +} +.alert[data-notify="container"] { + padding: 10px 10px 10px 20px; + border-radius: 4px; +} +.alert.alert-with-icon { + padding-left: 65px; +} + +.alert-info { + background-color: #63d8f1; +} + +.alert-success { + background-color: #a1e82c; +} + +.alert-warning { + background-color: #ffbc67; +} + +.alert-danger { + background-color: #fc727a; +} + +.table .radio, +.table .checkbox { + position: relative; + height: 20px; + display: block; + width: 20px; + padding: 0px 0px; + margin: 0px 5px; + text-align: center; +} +.table .radio .icons, +.table .checkbox .icons { + left: 5px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 12px 8px; + vertical-align: middle; +} +.table > thead > tr > th { + border-bottom-width: 1px; + font-size: 12px; + text-transform: uppercase; + color: #9A9A9A; + font-weight: 400; + padding-bottom: 5px; +} +.table .td-actions .btn { + opacity: 0.36; + filter: alpha(opacity=36); +} +.table .td-actions .btn.btn-xs { + padding-left: 3px; + padding-right: 3px; +} +.table .td-actions { + min-width: 90px; +} +.table > tbody > tr { + position: relative; +} +.table > tbody > tr:hover .td-actions .btn { + opacity: 1; + filter: alpha(opacity=100); +} + +/* Checkbox and radio */ +.checkbox, +.radio { + margin-bottom: 12px; + padding-left: 32px; + position: relative; + -webkit-transition: color 0.25s linear; + transition: color 0.25s linear; + font-size: 14px; + font-weight: normal; + line-height: 1.5; + color: #333333; +} + +.checkbox input, +.radio input { + outline: none !important; + display: none; +} + +.checkbox .icons, +.radio .icons { + color: #DDDDDD; + display: block; + height: 20px; + left: 0; + position: absolute; + top: 0; + width: 20px; + text-align: center; + line-height: 21px; + font-size: 20px; + cursor: pointer; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox .icons .first-icon, +.radio .icons .first-icon, +.checkbox .icons .second-icon, +.radio .icons .second-icon { + display: inline-table; + position: absolute; + left: 0; + top: 0; + background-color: transparent; + margin: 0; + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox .icons .second-icon, +.radio .icons .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover, +.radio:hover { + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox:hover .first-icon, +.radio:hover .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover .second-icon, +.radio:hover .second-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.checked, +.radio.checked { + color: #1DC7EA; +} + +.checkbox.checked .first-icon, +.radio.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.checked .second-icon, +.radio.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #1DC7EA; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox.disabled, +.radio.disabled { + cursor: default; + color: #DDDDDD !important; +} + +.checkbox.disabled .icons, +.radio.disabled .icons { + color: #DDDDDD !important; +} + +.checkbox.disabled .first-icon, +.radio.disabled .first-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.disabled .second-icon, +.radio.disabled .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .icons, +.radio.disabled.checked .icons { + color: #DDDDDD; +} + +.checkbox.disabled.checked .first-icon, +.radio.disabled.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .second-icon, +.radio.disabled.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #D9D9D9; +} + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ +.has-switch { + border-radius: 30px; + cursor: pointer; + display: inline-block; + line-height: 1.72222; + overflow: hidden; + position: relative; + text-align: left; + width: 60px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + /* this code is for fixing safari bug with hidden overflow for border-radius */ + -webkit-mask: url("../img/mask.png") 0 0 no-repeat; + -webkit-mask-size: 60px 24px; + mask: url("../img/mask.png") 0 0 no-repeat; +} + +.has-switch.deactivate { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} + +.has-switch.deactivate label, +.has-switch.deactivate span { + cursor: default !important; +} + +.has-switch > div { + position: relative; + top: 0; + width: 100px; +} + +.has-switch > div.switch-animate { + -webkit-transition: left 0.25s ease-out; + transition: left 0.25s ease-out; +} + +.has-switch > div.switch-off { + left: -35px; +} + +.has-switch > div.switch-on { + left: 0; +} + +.has-switch > div label { + background-color: #FFFFFF; + background: white; + background: -moz-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #f1f1f2)); + background: -webkit-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -o-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -ms-linear-gradient(top, white 0%, #f1f1f2 100%); + background: linear-gradient(to bottom, white 0%, #f1f1f2 100%); + background-size: 150% 150%; + box-shadow: 0 1px 1px #FFFFFF inset, 0 1px 1px rgba(0, 0, 0, 0.25); + cursor: pointer; +} + +.has-switch input[type=checkbox] { + display: none; +} + +.has-switch span { + /* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) inset; */ + cursor: pointer; + float: left; + font-size: 11px; + font-weight: 400; + height: 24px; + line-height: 15px; + margin: 0; + padding-bottom: 6px; + padding-top: 5px; + position: relative; + text-align: center; + text-indent: -10px; + width: 50%; + z-index: 1; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch span.switch-left { + background-color: #1DC7EA; + border-left: 1px solid transparent; + border-radius: 30px 0 0 30px; + color: #FFFFFF; +} + +.has-switch .switch-off span.switch-left { + background-color: #DDDDDD; +} + +.has-switch span.switch-right { + border-radius: 0 30px 30px 0; + background-color: #1DC7EA; + color: #ffffff; + text-indent: 1px; +} + +.has-switch .switch-off span.switch-right { + background-color: #DDDDDD; +} + +.has-switch label { + border-radius: 12px; + float: left; + height: 22px; + margin: 1px -13px; + padding: 0; + position: relative; + transition: all 0.25s ease-out 0s; + vertical-align: middle; + width: 22px; + z-index: 100; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch .switch-on .fa-check:before { + margin-left: 10px; +} + +.has-switch:hover .switch-on label { + margin: 1px -17px; + width: 26px; +} + +.has-switch:hover .switch-off label { + margin: 1px -13px; + width: 26px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: transparent; +} + +.navbar { + border: 0; + font-size: 16px; + border-radius: 0; +} +.navbar .navbar-brand { + font-weight: 400; + margin: 5px 0px; + padding: 15px 15px; + font-size: 20px; +} +.navbar .navbar-nav > li > a { + padding: 10px 15px; + margin: 10px 3px; + position: relative; +} +.navbar .navbar-nav > li > a.btn { + margin: 15px 3px; + padding: 8px 16px; +} +.navbar .navbar-nav > li > a.btn-round { + margin: 16px 3px; +} +.navbar .navbar-nav > li > a [class^="fa"] { + font-size: 19px; + position: relative; + line-height: 16px; + top: 1px; +} +.navbar .navbar-nav .notification { + position: absolute; + background-color: #FB404B; + text-align: center; + border-radius: 10px; + min-width: 18px; + padding: 0 5px; + height: 18px; + font-size: 12px; + color: #FFFFFF; + font-weight: bold; + line-height: 18px; + top: 0px; + left: 7px; +} +.navbar .btn { + margin: 15px 3px; + font-size: 14px; +} +.navbar .btn-simple { + font-size: 16px; +} +.navbar.fixed { + width: calc(100% - $sidebar-width); + right: 0; + left: auto; + border-radius: 0; +} + +.navbar-nav > li > .dropdown-menu { + border-radius: 10px; + margin-top: -5px; +} + +.navbar-transparent .navbar-brand, [class*="navbar-ct"] .navbar-brand { + color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .navbar-brand:focus, .navbar-transparent .navbar-brand:hover, [class*="navbar-ct"] .navbar-brand:focus, [class*="navbar-ct"] .navbar-brand:hover { + background-color: transparent; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav > li > a:not(.btn), [class*="navbar-ct"] .navbar-nav > li > a:not(.btn) { + color: #FFFFFF; + border-color: #FFFFFF; + opacity: 0.8; + filter: alpha(opacity=80); +} +.navbar-transparent .navbar-nav > .active > a:not(.btn), +.navbar-transparent .navbar-nav > .active > a:hover:not(.btn), +.navbar-transparent .navbar-nav > .active > a:focus:not(.btn), +.navbar-transparent .navbar-nav > li > a:hover:not(.btn), +.navbar-transparent .navbar-nav > li > a:focus:not(.btn), [class*="navbar-ct"] .navbar-nav > .active > a:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:focus:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:focus:not(.btn) { + background-color: transparent; + border-radius: 3px; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav .nav > li > a.btn:hover, [class*="navbar-ct"] .navbar-nav .nav > li > a.btn:hover { + background-color: transparent; +} +.navbar-transparent .navbar-nav > .dropdown > a .caret, +.navbar-transparent .navbar-nav > .dropdown > a:hover .caret, +.navbar-transparent .navbar-nav > .dropdown > a:focus .caret, [class*="navbar-ct"] .navbar-nav > .dropdown > a .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:hover .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} +.navbar-transparent .navbar-nav > .open > a, +.navbar-transparent .navbar-nav > .open > a:hover, +.navbar-transparent .navbar-nav > .open > a:focus, [class*="navbar-ct"] .navbar-nav > .open > a, +[class*="navbar-ct"] .navbar-nav > .open > a:hover, +[class*="navbar-ct"] .navbar-nav > .open > a:focus { + background-color: transparent; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .btn-default, [class*="navbar-ct"] .btn-default { + color: #FFFFFF; + border-color: #FFFFFF; +} +.navbar-transparent .btn-default.btn-fill, [class*="navbar-ct"] .btn-default.btn-fill { + color: #9A9A9A; + background-color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .btn-default.btn-fill:hover, +.navbar-transparent .btn-default.btn-fill:focus, +.navbar-transparent .btn-default.btn-fill:active, +.navbar-transparent .btn-default.btn-fill.active, +.navbar-transparent .open .dropdown-toggle.btn-fill.btn-default, [class*="navbar-ct"] .btn-default.btn-fill:hover, +[class*="navbar-ct"] .btn-default.btn-fill:focus, +[class*="navbar-ct"] .btn-default.btn-fill:active, +[class*="navbar-ct"] .btn-default.btn-fill.active, +[class*="navbar-ct"] .open .dropdown-toggle.btn-fill.btn-default { + border-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} + +.navbar-transparent .dropdown-menu .divider { + background-color: rgba(255, 255, 255, 0.2); +} + +.nav-open .nav .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} + +.navbar-default { + background-color: rgba(255, 255, 255, 0.96); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); +} +.navbar-default .navbar-nav > li > a:not(.btn) { + color: #9A9A9A; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:not(.btn):hover, +.navbar-default .navbar-nav > .active > a:not(.btn):focus, +.navbar-default .navbar-nav > li > a:not(.btn):hover, +.navbar-default .navbar-nav > li > a:not(.btn):focus { + background-color: transparent; + border-radius: 3px; + color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #1DC7EA; + border-top-color: #1DC7EA; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #1DC7EA; +} +.navbar-default .navbar-nav .navbar-toggle:hover, .navbar-default .navbar-nav .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default:not(.navbar-transparent) .btn-default:hover { + color: #1DC7EA; + border-color: #1DC7EA; +} +.navbar-default:not(.navbar-transparent) .btn-neutral, .navbar-default:not(.navbar-transparent) .btn-neutral:hover, .navbar-default:not(.navbar-transparent) .btn-neutral:active { + color: #9A9A9A; +} + +/* Navbar with icons */ +.navbar-icons.navbar .navbar-brand { + margin-top: 12px; + margin-bottom: 12px; +} +.navbar-icons .navbar-nav > li > a { + text-align: center; + padding: 6px 15px; + margin: 6px 3px; +} +.navbar-icons .navbar-nav [class^="pe"] { + font-size: 30px; + position: relative; +} +.navbar-icons .navbar-nav p { + margin: 3px 0 0; +} + +.navbar-form { + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form .form-control { + border-radius: 0; + border: 0; + padding: 0; + background-color: transparent; + height: 22px; + font-size: 16px; + line-height: 1.5; + color: #E3E3E3; +} +.navbar-transparent .navbar-form .form-control, [class*="navbar-ct"] .navbar-form .form-control { + color: #FFFFFF; + border: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.6); +} + +.navbar-ct-blue { + background-color: #4091e2; +} + +.navbar-ct-azure { + background-color: #63d8f1; +} + +.navbar-ct-green { + background-color: #a1e82c; +} + +.navbar-ct-orange { + background-color: #ffbc67; +} + +.navbar-ct-red { + background-color: #fc727a; +} + +.navbar-transparent { + padding-top: 15px; + background-color: transparent; + border-bottom: 1px solid transparent; +} + +.navbar-toggle { + margin-top: 19px; + margin-bottom: 19px; + border: 0; +} +.navbar-toggle .icon-bar { + background-color: #FFFFFF; +} +.navbar-toggle .navbar-collapse, +.navbar-toggle .navbar-form { + border-color: transparent; +} +.navbar-toggle.navbar-default .navbar-toggle:hover, .navbar-toggle.navbar-default .navbar-toggle:focus { + background-color: transparent; +} + +.footer { + background-color: #FFFFFF; + line-height: 20px; +} +.footer nav > ul { + list-style: none; + margin: 0; + padding: 0; + font-weight: normal; +} +.footer nav > ul a:not(.btn) { + color: #9A9A9A; + display: block; + margin-bottom: 3px; +} +.footer nav > ul a:not(.btn):hover, .footer nav > ul a:not(.btn):focus { + color: #777777; +} +.footer .social-area { + padding: 15px 0; +} +.footer .social-area h5 { + padding-bottom: 15px; +} +.footer .social-area > a:not(.btn) { + color: #9A9A9A; + display: inline-block; + vertical-align: top; + padding: 10px 5px; + font-size: 20px; + font-weight: normal; + line-height: 20px; + text-align: center; +} +.footer .social-area > a:not(.btn):hover, .footer .social-area > a:not(.btn):focus { + color: #777777; +} +.footer .copyright { + color: #777777; + padding: 10px 15px; + margin: 10px 3px; + line-height: 20px; + font-size: 14px; +} +.footer hr { + border-color: #DDDDDD; +} +.footer .title { + color: #777777; +} + +.footer-default { + background-color: #F5F5F5; +} + +.footer:not(.footer-big) nav > ul { + font-size: 14px; +} +.footer:not(.footer-big) nav > ul li { + margin-left: 20px; + float: left; +} +.footer:not(.footer-big) nav > ul a { + padding: 10px 0px; + margin: 10px 10px 10px 0px; +} + +.dropdown-menu { + visibility: hidden; + margin: 0; + padding: 0; + border-radius: 10px; + display: block; + z-index: 9000; + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); +} +.open .dropdown-menu { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; +} +.select .dropdown-menu { + border-radius: 0 0 10px 10px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transform-origin: 50% -40px; + -moz-transform-origin: 50% -40px; + -o-transform-origin: 50% -40px; + -ms-transform-origin: 50% -40px; + transform-origin: 50% -40px; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transition: all 150ms linear; + -moz-transition: all 150ms linear; + -o-transition: all 150ms linear; + -ms-transition: all 150ms linear; + transition: all 150ms linear; + margin-top: -20px; +} +.select.open .dropdown-menu { + margin-top: -1px; +} +.dropdown-menu > li > a { + padding: 8px 16px; + color: #333333; +} +.dropdown-menu > li > a img { + margin-top: -3px; +} +.dropdown-menu > li > a:focus { + outline: 0 !important; +} +.btn-group.select .dropdown-menu { + min-width: 100%; +} +.dropdown-menu > li:first-child > a { + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} +.dropdown-menu > li:last-child > a { + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} +.select .dropdown-menu > li:first-child > a { + border-radius: 0; + border-bottom: 0 none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #F5F5F5; + color: #333333; + opacity: 1; + text-decoration: none; +} +.dropdown-menu.dropdown-blue > li > a:hover, .dropdown-menu.dropdown-blue > li > a:focus { + background-color: rgba(52, 114, 247, 0.2); +} +.dropdown-menu.dropdown-azure > li > a:hover, .dropdown-menu.dropdown-azure > li > a:focus { + background-color: rgba(29, 199, 234, 0.2); +} +.dropdown-menu.ct-green > li > a:hover, .dropdown-menu.ct-green > li > a:focus { + background-color: rgba(135, 203, 22, 0.2); +} +.dropdown-menu.dropdown-orange > li > a:hover, .dropdown-menu.dropdown-orange > li > a:focus { + background-color: rgba(255, 149, 0, 0.2); +} +.dropdown-menu.dropdown-red > li > a:hover, .dropdown-menu.dropdown-red > li > a:focus { + background-color: rgba(255, 74, 85, 0.2); +} + +.dropdown-with-icons > li > a { + padding-left: 0px; + line-height: 28px; +} +.dropdown-with-icons i { + text-align: center; + line-height: 28px; + float: left; +} +.dropdown-with-icons i[class^="pe-"] { + font-size: 24px; + width: 46px; +} +.dropdown-with-icons i[class^="fa"] { + font-size: 14px; + width: 38px; +} + +.btn-group.select { + overflow: hidden; +} + +.btn-group.select.open { + overflow: visible; +} + +.card { + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(63, 63, 68, 0.1); + background-color: #FFFFFF; + margin-bottom: 30px; +} +.card .image { + width: 100%; + overflow: hidden; + height: 260px; + border-radius: 4px 4px 0 0; + position: relative; + -webkit-transform-style: preserve-3d; + -moz-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.card .image img { + width: 100%; +} +.card .filter { + position: absolute; + z-index: 2; + background-color: rgba(0, 0, 0, 0.68); + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + filter: alpha(opacity=0); +} +.card .filter .btn { + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} +.card:hover .filter { + opacity: 1; + filter: alpha(opacity=100); +} +.card .btn-hover { + opacity: 0; + filter: alpha(opacity=0); +} +.card:hover .btn-hover { + opacity: 1; + filter: alpha(opacity=100); +} +.card .content { + padding: 15px 15px 10px 15px; +} +.card .header { + padding: 15px 15px 0; +} +.card .category, +.card label { + font-size: 14px; + font-weight: 400; + color: #9A9A9A; + margin-bottom: 0px; +} +.card .category i, +.card label i { + font-size: 16px; +} +.card label { + font-size: 12px; + margin-bottom: 5px; + text-transform: uppercase; +} +.card .title { + margin: 0; + color: #333333; + font-weight: 300; +} +.card .avatar { + width: 30px; + height: 30px; + overflow: hidden; + border-radius: 50%; + margin-right: 5px; +} +.card .description { + font-size: 14px; + color: #333; +} +.card .footer { + padding: 0; + background-color: transparent; + line-height: 30px; +} +.card .footer .legend { + padding: 5px 0; +} +.card .footer hr { + margin-top: 5px; + margin-bottom: 5px; +} +.card .stats { + color: #a9a9a9; +} +.card .footer div { + display: inline-block; +} +.card .author { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.card .author i { + font-size: 14px; +} +.card h6 { + font-size: 12px; + margin: 0; +} +.card.card-separator:after { + height: 100%; + right: -15px; + top: 0; + width: 1px; + background-color: #DDDDDD; + content: ""; + position: absolute; +} +.card .ct-chart { + margin: 30px 0 30px; + height: 245px; +} +.card .table tbody td:first-child, +.card .table thead th:first-child { + padding-left: 15px; +} +.card .table tbody td:last-child, +.card .table thead th:last-child { + padding-right: 15px; +} +.card .alert { + border-radius: 4px; + position: relative; +} +.card .alert.alert-with-icon { + padding-left: 65px; +} + +.card-user .image { + height: 110px; +} +.card-user .image-plain { + height: 0; + margin-top: 110px; +} +.card-user .author { + text-align: center; + text-transform: none; + margin-top: -70px; +} +.card-user .avatar { + width: 124px; + height: 124px; + border: 5px solid #FFFFFF; + position: relative; + margin-bottom: 15px; +} +.card-user .avatar.border-gray { + border-color: #EEEEEE; +} +.card-user .title { + line-height: 24px; +} +.card-user .content { + min-height: 240px; +} + +.card-user .footer, +.card-price .footer { + padding: 5px 15px 10px; +} +.card-user hr, +.card-price hr { + margin: 5px 15px; +} + +.card-plain { + background-color: transparent; + box-shadow: none; + border-radius: 0; +} +.card-plain .image { + border-radius: 4px; +} + +.ct-label { + fill: rgba(0, 0, 0, 0.4); + color: rgba(0, 0, 0, 0.4); + font-size: 1.3rem; + line-height: 1; +} + +.ct-chart-line .ct-label, +.ct-chart-bar .ct-label { + display: block; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-vertical.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-label.ct-vertical.ct-end { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: end; +} + +.ct-grid { + stroke: rgba(0, 0, 0, 0.2); + stroke-width: 1px; + stroke-dasharray: 2px; +} + +.ct-point { + stroke-width: 8px; + stroke-linecap: round; +} + +.ct-line { + fill: none; + stroke-width: 3px; +} + +.ct-area { + stroke: none; + fill-opacity: 0.8; +} + +.ct-bar { + fill: none; + stroke-width: 10px; +} + +.ct-slice-donut { + fill: none; + stroke-width: 60px; +} + +.ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut { + stroke: #1DC7EA; +} +.ct-series-a .ct-slice-pie, .ct-series-a .ct-area { + fill: #1DC7EA; +} + +.ct-series-b .ct-point, .ct-series-b .ct-line, .ct-series-b .ct-bar, .ct-series-b .ct-slice-donut { + stroke: #FB404B; +} +.ct-series-b .ct-slice-pie, .ct-series-b .ct-area { + fill: #FB404B; +} + +.ct-series-c .ct-point, .ct-series-c .ct-line, .ct-series-c .ct-bar, .ct-series-c .ct-slice-donut { + stroke: #FFA534; +} +.ct-series-c .ct-slice-pie, .ct-series-c .ct-area { + fill: #FFA534; +} + +.ct-series-d .ct-point, .ct-series-d .ct-line, .ct-series-d .ct-bar, .ct-series-d .ct-slice-donut { + stroke: #9368E9; +} +.ct-series-d .ct-slice-pie, .ct-series-d .ct-area { + fill: #9368E9; +} + +.ct-series-e .ct-point, .ct-series-e .ct-line, .ct-series-e .ct-bar, .ct-series-e .ct-slice-donut { + stroke: #87CB16; +} +.ct-series-e .ct-slice-pie, .ct-series-e .ct-area { + fill: #87CB16; +} + +.ct-series-f .ct-point, .ct-series-f .ct-line, .ct-series-f .ct-bar, .ct-series-f .ct-slice-donut { + stroke: #1F77D0; +} +.ct-series-f .ct-slice-pie, .ct-series-f .ct-area { + fill: #1F77D0; +} + +.ct-series-g .ct-point, .ct-series-g .ct-line, .ct-series-g .ct-bar, .ct-series-g .ct-slice-donut { + stroke: #5e5e5e; +} +.ct-series-g .ct-slice-pie, .ct-series-g .ct-area { + fill: #5e5e5e; +} + +.ct-series-h .ct-point, .ct-series-h .ct-line, .ct-series-h .ct-bar, .ct-series-h .ct-slice-donut { + stroke: #dd4b39; +} +.ct-series-h .ct-slice-pie, .ct-series-h .ct-area { + fill: #dd4b39; +} + +.ct-series-i .ct-point, .ct-series-i .ct-line, .ct-series-i .ct-bar, .ct-series-i .ct-slice-donut { + stroke: #35465c; +} +.ct-series-i .ct-slice-pie, .ct-series-i .ct-area { + fill: #35465c; +} + +.ct-series-j .ct-point, .ct-series-j .ct-line, .ct-series-j .ct-bar, .ct-series-j .ct-slice-donut { + stroke: #e52d27; +} +.ct-series-j .ct-slice-pie, .ct-series-j .ct-area { + fill: #e52d27; +} + +.ct-series-k .ct-point, .ct-series-k .ct-line, .ct-series-k .ct-bar, .ct-series-k .ct-slice-donut { + stroke: #55acee; +} +.ct-series-k .ct-slice-pie, .ct-series-k .ct-area { + fill: #55acee; +} + +.ct-series-l .ct-point, .ct-series-l .ct-line, .ct-series-l .ct-bar, .ct-series-l .ct-slice-donut { + stroke: #cc2127; +} +.ct-series-l .ct-slice-pie, .ct-series-l .ct-area { + fill: #cc2127; +} + +.ct-series-m .ct-point, .ct-series-m .ct-line, .ct-series-m .ct-bar, .ct-series-m .ct-slice-donut { + stroke: #1769ff; +} +.ct-series-m .ct-slice-pie, .ct-series-m .ct-area { + fill: #1769ff; +} + +.ct-series-n .ct-point, .ct-series-n .ct-line, .ct-series-n .ct-bar, .ct-series-n .ct-slice-donut { + stroke: #6188e2; +} +.ct-series-n .ct-slice-pie, .ct-series-n .ct-area { + fill: #6188e2; +} + +.ct-series-o .ct-point, .ct-series-o .ct-line, .ct-series-o .ct-bar, .ct-series-o .ct-slice-donut { + stroke: #a748ca; +} +.ct-series-o .ct-slice-pie, .ct-series-o .ct-area { + fill: #a748ca; +} + +.ct-square { + display: block; + position: relative; + width: 100%; +} +.ct-square:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 100%; +} +.ct-square:after { + content: ""; + display: table; + clear: both; +} +.ct-square > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-second { + display: block; + position: relative; + width: 100%; +} +.ct-minor-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 93.75%; +} +.ct-minor-second:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-second { + display: block; + position: relative; + width: 100%; +} +.ct-major-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 88.88889%; +} +.ct-major-second:after { + content: ""; + display: table; + clear: both; +} +.ct-major-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-third { + display: block; + position: relative; + width: 100%; +} +.ct-minor-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 83.33333%; +} +.ct-minor-third:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-third { + display: block; + position: relative; + width: 100%; +} +.ct-major-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 80%; +} +.ct-major-third:after { + content: ""; + display: table; + clear: both; +} +.ct-major-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fourth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fourth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 75%; +} +.ct-perfect-fourth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fourth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fifth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fifth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 66.66667%; +} +.ct-perfect-fifth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fifth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-minor-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 62.5%; +} +.ct-minor-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-golden-section { + display: block; + position: relative; + width: 100%; +} +.ct-golden-section:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 61.8047%; +} +.ct-golden-section:after { + content: ""; + display: table; + clear: both; +} +.ct-golden-section > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-major-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 60%; +} +.ct-major-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-minor-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 56.25%; +} +.ct-minor-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 53.33333%; +} +.ct-major-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-octave { + display: block; + position: relative; + width: 100%; +} +.ct-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 50%; +} +.ct-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-tenth { + display: block; + position: relative; + width: 100%; +} +.ct-major-tenth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 40%; +} +.ct-major-tenth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-tenth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-eleventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-eleventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 37.5%; +} +.ct-major-eleventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-eleventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-twelfth { + display: block; + position: relative; + width: 100%; +} +.ct-major-twelfth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 33.33333%; +} +.ct-major-twelfth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-twelfth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-double-octave { + display: block; + position: relative; + width: 100%; +} +.ct-double-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 25%; +} +.ct-double-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-double-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +@media (min-width: 992px) { + .navbar-form { + margin-top: 21px; + margin-bottom: 21px; + padding-left: 5px; + padding-right: 5px; + } + + .navbar-nav > li > .dropdown-menu, .dropdown .dropdown-menu { + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -moz-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -o-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -ms-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + } + + .navbar-nav > li.open > .dropdown-menu, .dropdown.open .dropdown-menu { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transform-origin: 29px -50px; + -moz-transform-origin: 29px -50px; + -o-transform-origin: 29px -50px; + -ms-transform-origin: 29px -50px; + transform-origin: 29px -50px; + } + + .navbar-nav > li > .dropdown-menu:before { + border-bottom: 11px solid rgba(0, 0, 0, 0.2); + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -11px; + } + + .navbar-nav > li > .dropdown-menu:after { + border-bottom: 11px solid #FFFFFF; + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -10px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:before { + left: auto; + right: 12px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:after { + left: auto; + right: 12px; + } + + .footer:not(.footer-big) nav > ul li:first-child { + margin-left: 0; + } + + body > .navbar-collapse.collapse { + display: none !important; + } + + .card form [class*="col-"] { + padding: 6px; + } + .card form [class*="col-"]:first-child { + padding-left: 15px; + } + .card form [class*="col-"]:last-child { + padding-right: 15px; + } +} +/* Changes for small display */ +@media (max-width: 991px) { + .sidebar { + display: none; + } + + .main-panel { + width: 100%; + } + + .navbar-transparent { + padding-top: 15px; + background-color: rgba(0, 0, 0, 0.45); + } + + body { + position: relative; + } + + .wrapper { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + left: 0; + background-color: white; + } + + .navbar .container { + left: 0; + width: 100%; + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + position: relative; + } + + .navbar .navbar-collapse.collapse, + .navbar .navbar-collapse.collapse.in, + .navbar .navbar-collapse.collapsing { + display: none !important; + } + + .navbar-nav > li { + float: none; + position: relative; + display: block; + } + + body > .navbar-collapse { + position: fixed; + display: block; + top: 0; + height: 100%; + width: 250px; + right: 0; + z-index: 1032; + visibility: visible; + background-color: #999; + overflow-y: visible; + border-top: none; + text-align: left; + padding: 0; + -webkit-transform: translate3d(250px, 0, 0); + -moz-transform: translate3d(250px, 0, 0); + -o-transform: translate3d(250px, 0, 0); + -ms-transform: translate3d(250px, 0, 0); + transform: translate3d(250px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + } + body > .navbar-collapse > ul { + position: relative; + z-index: 4; + overflow-y: scroll; + height: calc(100vh - 61px); + width: 100%; + } + body > .navbar-collapse .nav > li > a { + padding: 30px 25px; + } + body > .navbar-collapse::before { + top: 0; + left: 0; + height: 100%; + width: 100%; + position: absolute; + background-color: #282828; + display: block; + content: ""; + z-index: 1; + } + body > .navbar-collapse .logo { + position: relative; + z-index: 4; + } + + .nav-open .navbar-collapse { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + } + + .nav-open .navbar .container { + left: -250px; + } + + .nav-open .wrapper { + left: 0; + -webkit-transform: translate3d(-250px, 0, 0); + -moz-transform: translate3d(-250px, 0, 0); + -o-transform: translate3d(-250px, 0, 0); + -ms-transform: translate3d(-250px, 0, 0); + transform: translate3d(-250px, 0, 0); + } + + .navbar-toggle .icon-bar { + display: block; + position: relative; + background: #fff; + width: 24px; + height: 2px; + border-radius: 1px; + margin: 0 auto; + } + + .navbar-header .navbar-toggle { + margin: 10px 15px 10px 0; + width: 40px; + height: 40px; + } + + .bar1, + .bar2, + .bar3 { + outline: 1px solid transparent; + } + + .bar1 { + top: 0px; + -webkit-animation: topbar-back 500ms linear 0s; + -moz-animation: topbar-back 500ms linear 0s; + animation: topbar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .bar2 { + opacity: 1; + } + + .bar3 { + bottom: 0px; + -webkit-animation: bottombar-back 500ms linear 0s; + -moz-animation: bottombar-back 500ms linear 0s; + animation: bottombar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar1 { + top: 6px; + -webkit-animation: topbar-x 500ms linear 0s; + -moz-animation: topbar-x 500ms linear 0s; + animation: topbar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar2 { + opacity: 0; + } + + .toggled .bar3 { + bottom: 6px; + -webkit-animation: bottombar-x 500ms linear 0s; + -moz-animation: bottombar-x 500ms linear 0s; + animation: bottombar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + @keyframes topbar-x { + 0% { + top: 0px; + transform: rotate(0deg); + } + 45% { + top: 6px; + transform: rotate(145deg); + } + 75% { + transform: rotate(130deg); + } + 100% { + transform: rotate(135deg); + } + } + @-webkit-keyframes topbar-x { + 0% { + top: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + top: 6px; + -webkit-transform: rotate(145deg); + } + 75% { + -webkit-transform: rotate(130deg); + } + 100% { + -webkit-transform: rotate(135deg); + } + } + @-moz-keyframes topbar-x { + 0% { + top: 0px; + -moz-transform: rotate(0deg); + } + 45% { + top: 6px; + -moz-transform: rotate(145deg); + } + 75% { + -moz-transform: rotate(130deg); + } + 100% { + -moz-transform: rotate(135deg); + } + } + @keyframes topbar-back { + 0% { + top: 6px; + transform: rotate(135deg); + } + 45% { + transform: rotate(-10deg); + } + 75% { + transform: rotate(5deg); + } + 100% { + top: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes topbar-back { + 0% { + top: 6px; + -webkit-transform: rotate(135deg); + } + 45% { + -webkit-transform: rotate(-10deg); + } + 75% { + -webkit-transform: rotate(5deg); + } + 100% { + top: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes topbar-back { + 0% { + top: 6px; + -moz-transform: rotate(135deg); + } + 45% { + -moz-transform: rotate(-10deg); + } + 75% { + -moz-transform: rotate(5deg); + } + 100% { + top: 0px; + -moz-transform: rotate(0); + } + } + @keyframes bottombar-x { + 0% { + bottom: 0px; + transform: rotate(0deg); + } + 45% { + bottom: 6px; + transform: rotate(-145deg); + } + 75% { + transform: rotate(-130deg); + } + 100% { + transform: rotate(-135deg); + } + } + @-webkit-keyframes bottombar-x { + 0% { + bottom: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -webkit-transform: rotate(-145deg); + } + 75% { + -webkit-transform: rotate(-130deg); + } + 100% { + -webkit-transform: rotate(-135deg); + } + } + @-moz-keyframes bottombar-x { + 0% { + bottom: 0px; + -moz-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -moz-transform: rotate(-145deg); + } + 75% { + -moz-transform: rotate(-130deg); + } + 100% { + -moz-transform: rotate(-135deg); + } + } + @keyframes bottombar-back { + 0% { + bottom: 6px; + transform: rotate(-135deg); + } + 45% { + transform: rotate(10deg); + } + 75% { + transform: rotate(-5deg); + } + 100% { + bottom: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes bottombar-back { + 0% { + bottom: 6px; + -webkit-transform: rotate(-135deg); + } + 45% { + -webkit-transform: rotate(10deg); + } + 75% { + -webkit-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes bottombar-back { + 0% { + bottom: 6px; + -moz-transform: rotate(-135deg); + } + 45% { + -moz-transform: rotate(10deg); + } + 75% { + -moz-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -moz-transform: rotate(0); + } + } + @-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @-moz-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + .dropdown-menu .divider { + background-color: rgba(229, 229, 229, 0.15); + } + + .navbar-nav { + margin: 1px 0; + } + .navbar-nav .open .dropdown-menu > li > a { + padding: 15px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:first-child > a { + padding: 5px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:last-child > a { + padding: 15px 15px 25px 50px; + } + + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .active > a, + [class*="navbar-"] .navbar-nav .active > a:hover, + [class*="navbar-"] .navbar-nav .active > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus, + [class*="navbar-"] .navbar-nav .navbar-nav .open .dropdown-menu > li > a:active { + color: white; + } + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus { + opacity: .7; + background: transparent; + } + [class*="navbar-"] .navbar-nav.navbar-nav .open .dropdown-menu > li > a:active { + opacity: 1; + } + [class*="navbar-"] .navbar-nav .dropdown > a:hover .caret { + border-bottom-color: #777; + border-top-color: #777; + } + [class*="navbar-"] .navbar-nav .dropdown > a:active .caret { + border-bottom-color: white; + border-top-color: white; + } + + .dropdown-menu { + display: none; + } + + .navbar-fixed-top { + -webkit-backface-visibility: hidden; + } + + #bodyClick { + height: 100%; + width: 100%; + position: fixed; + opacity: 0; + top: 0; + left: auto; + right: 250px; + content: ""; + z-index: 9999; + overflow-x: hidden; + } + + .social-line .btn { + margin: 0 0 10px 0; + } + + .subscribe-line .form-control { + margin: 0 0 10px 0; + } + + .social-line.pull-right { + float: none; + } + + .footer nav.pull-left { + float: none !important; + } + + .footer:not(.footer-big) nav > ul li { + float: none; + } + + .social-area.pull-right { + float: none !important; + } + + .form-control + .form-control-feedback { + margin-top: -8px; + } + + .navbar-toggle:hover, .navbar-toggle:focus { + background-color: transparent !important; + } + + .btn.dropdown-toggle { + margin-bottom: 0; + } + + .media-post .author { + width: 20%; + float: none !important; + display: block; + margin: 0 auto 10px; + } + + .media-post .media-body { + width: 100%; + } + + .navbar-collapse.collapse { + height: 100% !important; + } + + .navbar-collapse.collapse.in { + display: block; + } + + .navbar-header .collapse, .navbar-toggle { + display: block !important; + } + + .navbar-header { + float: none; + } + + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + + .navbar-collapse .nav p { + font-size: 14px; + margin: 0; + } + .navbar-collapse [class^="pe-7s-"] { + float: left; + font-size: 20px; + margin-right: 10px; + } +} +@media (min-width: 992px) { + .table-full-width { + margin-left: -15px; + margin-right: -15px; + } + + .table-responsive { + overflow: visible; + } +} +@media (max-width: 991px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; + } +} diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/pe-icon-7-stroke.css b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/pe-icon-7-stroke.css new file mode 100644 index 0000000..44bcbaa --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/css/pe-icon-7-stroke.css @@ -0,0 +1,632 @@ +@font-face { + font-family: 'Pe-icon-7-stroke'; + src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v'); + src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'), + url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'), + url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'), + url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="pe-7s-"], [class*=" pe-7s-"] { + display: inline-block; + font-family: 'Pe-icon-7-stroke'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.pe-7s-album:before { + content: "\e6aa"; +} +.pe-7s-arc:before { + content: "\e6ab"; +} +.pe-7s-back-2:before { + content: "\e6ac"; +} +.pe-7s-bandaid:before { + content: "\e6ad"; +} +.pe-7s-car:before { + content: "\e6ae"; +} +.pe-7s-diamond:before { + content: "\e6af"; +} +.pe-7s-door-lock:before { + content: "\e6b0"; +} +.pe-7s-eyedropper:before { + content: "\e6b1"; +} +.pe-7s-female:before { + content: "\e6b2"; +} +.pe-7s-gym:before { + content: "\e6b3"; +} +.pe-7s-hammer:before { + content: "\e6b4"; +} +.pe-7s-headphones:before { + content: "\e6b5"; +} +.pe-7s-helm:before { + content: "\e6b6"; +} +.pe-7s-hourglass:before { + content: "\e6b7"; +} +.pe-7s-leaf:before { + content: "\e6b8"; +} +.pe-7s-magic-wand:before { + content: "\e6b9"; +} +.pe-7s-male:before { + content: "\e6ba"; +} +.pe-7s-map-2:before { + content: "\e6bb"; +} +.pe-7s-next-2:before { + content: "\e6bc"; +} +.pe-7s-paint-bucket:before { + content: "\e6bd"; +} +.pe-7s-pendrive:before { + content: "\e6be"; +} +.pe-7s-photo:before { + content: "\e6bf"; +} +.pe-7s-piggy:before { + content: "\e6c0"; +} +.pe-7s-plugin:before { + content: "\e6c1"; +} +.pe-7s-refresh-2:before { + content: "\e6c2"; +} +.pe-7s-rocket:before { + content: "\e6c3"; +} +.pe-7s-settings:before { + content: "\e6c4"; +} +.pe-7s-shield:before { + content: "\e6c5"; +} +.pe-7s-smile:before { + content: "\e6c6"; +} +.pe-7s-usb:before { + content: "\e6c7"; +} +.pe-7s-vector:before { + content: "\e6c8"; +} +.pe-7s-wine:before { + content: "\e6c9"; +} +.pe-7s-cloud-upload:before { + content: "\e68a"; +} +.pe-7s-cash:before { + content: "\e68c"; +} +.pe-7s-close:before { + content: "\e680"; +} +.pe-7s-bluetooth:before { + content: "\e68d"; +} +.pe-7s-cloud-download:before { + content: "\e68b"; +} +.pe-7s-way:before { + content: "\e68e"; +} +.pe-7s-close-circle:before { + content: "\e681"; +} +.pe-7s-id:before { + content: "\e68f"; +} +.pe-7s-angle-up:before { + content: "\e682"; +} +.pe-7s-wristwatch:before { + content: "\e690"; +} +.pe-7s-angle-up-circle:before { + content: "\e683"; +} +.pe-7s-world:before { + content: "\e691"; +} +.pe-7s-angle-right:before { + content: "\e684"; +} +.pe-7s-volume:before { + content: "\e692"; +} +.pe-7s-angle-right-circle:before { + content: "\e685"; +} +.pe-7s-users:before { + content: "\e693"; +} +.pe-7s-angle-left:before { + content: "\e686"; +} +.pe-7s-user-female:before { + content: "\e694"; +} +.pe-7s-angle-left-circle:before { + content: "\e687"; +} +.pe-7s-up-arrow:before { + content: "\e695"; +} +.pe-7s-angle-down:before { + content: "\e688"; +} +.pe-7s-switch:before { + content: "\e696"; +} +.pe-7s-angle-down-circle:before { + content: "\e689"; +} +.pe-7s-scissors:before { + content: "\e697"; +} +.pe-7s-wallet:before { + content: "\e600"; +} +.pe-7s-safe:before { + content: "\e698"; +} +.pe-7s-volume2:before { + content: "\e601"; +} +.pe-7s-volume1:before { + content: "\e602"; +} +.pe-7s-voicemail:before { + content: "\e603"; +} +.pe-7s-video:before { + content: "\e604"; +} +.pe-7s-user:before { + content: "\e605"; +} +.pe-7s-upload:before { + content: "\e606"; +} +.pe-7s-unlock:before { + content: "\e607"; +} +.pe-7s-umbrella:before { + content: "\e608"; +} +.pe-7s-trash:before { + content: "\e609"; +} +.pe-7s-tools:before { + content: "\e60a"; +} +.pe-7s-timer:before { + content: "\e60b"; +} +.pe-7s-ticket:before { + content: "\e60c"; +} +.pe-7s-target:before { + content: "\e60d"; +} +.pe-7s-sun:before { + content: "\e60e"; +} +.pe-7s-study:before { + content: "\e60f"; +} +.pe-7s-stopwatch:before { + content: "\e610"; +} +.pe-7s-star:before { + content: "\e611"; +} +.pe-7s-speaker:before { + content: "\e612"; +} +.pe-7s-signal:before { + content: "\e613"; +} +.pe-7s-shuffle:before { + content: "\e614"; +} +.pe-7s-shopbag:before { + content: "\e615"; +} +.pe-7s-share:before { + content: "\e616"; +} +.pe-7s-server:before { + content: "\e617"; +} +.pe-7s-search:before { + content: "\e618"; +} +.pe-7s-film:before { + content: "\e6a5"; +} +.pe-7s-science:before { + content: "\e619"; +} +.pe-7s-disk:before { + content: "\e6a6"; +} +.pe-7s-ribbon:before { + content: "\e61a"; +} +.pe-7s-repeat:before { + content: "\e61b"; +} +.pe-7s-refresh:before { + content: "\e61c"; +} +.pe-7s-add-user:before { + content: "\e6a9"; +} +.pe-7s-refresh-cloud:before { + content: "\e61d"; +} +.pe-7s-paperclip:before { + content: "\e69c"; +} +.pe-7s-radio:before { + content: "\e61e"; +} +.pe-7s-note2:before { + content: "\e69d"; +} +.pe-7s-print:before { + content: "\e61f"; +} +.pe-7s-network:before { + content: "\e69e"; +} +.pe-7s-prev:before { + content: "\e620"; +} +.pe-7s-mute:before { + content: "\e69f"; +} +.pe-7s-power:before { + content: "\e621"; +} +.pe-7s-medal:before { + content: "\e6a0"; +} +.pe-7s-portfolio:before { + content: "\e622"; +} +.pe-7s-like2:before { + content: "\e6a1"; +} +.pe-7s-plus:before { + content: "\e623"; +} +.pe-7s-left-arrow:before { + content: "\e6a2"; +} +.pe-7s-play:before { + content: "\e624"; +} +.pe-7s-key:before { + content: "\e6a3"; +} +.pe-7s-plane:before { + content: "\e625"; +} +.pe-7s-joy:before { + content: "\e6a4"; +} +.pe-7s-photo-gallery:before { + content: "\e626"; +} +.pe-7s-pin:before { + content: "\e69b"; +} +.pe-7s-phone:before { + content: "\e627"; +} +.pe-7s-plug:before { + content: "\e69a"; +} +.pe-7s-pen:before { + content: "\e628"; +} +.pe-7s-right-arrow:before { + content: "\e699"; +} +.pe-7s-paper-plane:before { + content: "\e629"; +} +.pe-7s-delete-user:before { + content: "\e6a7"; +} +.pe-7s-paint:before { + content: "\e62a"; +} +.pe-7s-bottom-arrow:before { + content: "\e6a8"; +} +.pe-7s-notebook:before { + content: "\e62b"; +} +.pe-7s-note:before { + content: "\e62c"; +} +.pe-7s-next:before { + content: "\e62d"; +} +.pe-7s-news-paper:before { + content: "\e62e"; +} +.pe-7s-musiclist:before { + content: "\e62f"; +} +.pe-7s-music:before { + content: "\e630"; +} +.pe-7s-mouse:before { + content: "\e631"; +} +.pe-7s-more:before { + content: "\e632"; +} +.pe-7s-moon:before { + content: "\e633"; +} +.pe-7s-monitor:before { + content: "\e634"; +} +.pe-7s-micro:before { + content: "\e635"; +} +.pe-7s-menu:before { + content: "\e636"; +} +.pe-7s-map:before { + content: "\e637"; +} +.pe-7s-map-marker:before { + content: "\e638"; +} +.pe-7s-mail:before { + content: "\e639"; +} +.pe-7s-mail-open:before { + content: "\e63a"; +} +.pe-7s-mail-open-file:before { + content: "\e63b"; +} +.pe-7s-magnet:before { + content: "\e63c"; +} +.pe-7s-loop:before { + content: "\e63d"; +} +.pe-7s-look:before { + content: "\e63e"; +} +.pe-7s-lock:before { + content: "\e63f"; +} +.pe-7s-lintern:before { + content: "\e640"; +} +.pe-7s-link:before { + content: "\e641"; +} +.pe-7s-like:before { + content: "\e642"; +} +.pe-7s-light:before { + content: "\e643"; +} +.pe-7s-less:before { + content: "\e644"; +} +.pe-7s-keypad:before { + content: "\e645"; +} +.pe-7s-junk:before { + content: "\e646"; +} +.pe-7s-info:before { + content: "\e647"; +} +.pe-7s-home:before { + content: "\e648"; +} +.pe-7s-help2:before { + content: "\e649"; +} +.pe-7s-help1:before { + content: "\e64a"; +} +.pe-7s-graph3:before { + content: "\e64b"; +} +.pe-7s-graph2:before { + content: "\e64c"; +} +.pe-7s-graph1:before { + content: "\e64d"; +} +.pe-7s-graph:before { + content: "\e64e"; +} +.pe-7s-global:before { + content: "\e64f"; +} +.pe-7s-gleam:before { + content: "\e650"; +} +.pe-7s-glasses:before { + content: "\e651"; +} +.pe-7s-gift:before { + content: "\e652"; +} +.pe-7s-folder:before { + content: "\e653"; +} +.pe-7s-flag:before { + content: "\e654"; +} +.pe-7s-filter:before { + content: "\e655"; +} +.pe-7s-file:before { + content: "\e656"; +} +.pe-7s-expand1:before { + content: "\e657"; +} +.pe-7s-exapnd2:before { + content: "\e658"; +} +.pe-7s-edit:before { + content: "\e659"; +} +.pe-7s-drop:before { + content: "\e65a"; +} +.pe-7s-drawer:before { + content: "\e65b"; +} +.pe-7s-download:before { + content: "\e65c"; +} +.pe-7s-display2:before { + content: "\e65d"; +} +.pe-7s-display1:before { + content: "\e65e"; +} +.pe-7s-diskette:before { + content: "\e65f"; +} +.pe-7s-date:before { + content: "\e660"; +} +.pe-7s-cup:before { + content: "\e661"; +} +.pe-7s-culture:before { + content: "\e662"; +} +.pe-7s-crop:before { + content: "\e663"; +} +.pe-7s-credit:before { + content: "\e664"; +} +.pe-7s-copy-file:before { + content: "\e665"; +} +.pe-7s-config:before { + content: "\e666"; +} +.pe-7s-compass:before { + content: "\e667"; +} +.pe-7s-comment:before { + content: "\e668"; +} +.pe-7s-coffee:before { + content: "\e669"; +} +.pe-7s-cloud:before { + content: "\e66a"; +} +.pe-7s-clock:before { + content: "\e66b"; +} +.pe-7s-check:before { + content: "\e66c"; +} +.pe-7s-chat:before { + content: "\e66d"; +} +.pe-7s-cart:before { + content: "\e66e"; +} +.pe-7s-camera:before { + content: "\e66f"; +} +.pe-7s-call:before { + content: "\e670"; +} +.pe-7s-calculator:before { + content: "\e671"; +} +.pe-7s-browser:before { + content: "\e672"; +} +.pe-7s-box2:before { + content: "\e673"; +} +.pe-7s-box1:before { + content: "\e674"; +} +.pe-7s-bookmarks:before { + content: "\e675"; +} +.pe-7s-bicycle:before { + content: "\e676"; +} +.pe-7s-bell:before { + content: "\e677"; +} +.pe-7s-battery:before { + content: "\e678"; +} +.pe-7s-ball:before { + content: "\e679"; +} +.pe-7s-back:before { + content: "\e67a"; +} +.pe-7s-attention:before { + content: "\e67b"; +} +.pe-7s-anchor:before { + content: "\e67c"; +} +.pe-7s-albums:before { + content: "\e67d"; +} +.pe-7s-alarm:before { + content: "\e67e"; +} +.pe-7s-airplay:before { + content: "\e67f"; +} diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot new file mode 100644 index 0000000000000000000000000000000000000000..6f7b58489c6fe76af1597fad93bd8ebe36114eb9 GIT binary patch literal 58680 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 Nxi7{(cl`%H{|#3vvLpZi literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg new file mode 100644 index 0000000..13d9709 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg @@ -0,0 +1,212 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bc8a269c68dafaaf5aaa7920e7a17baff0748360 GIT binary patch literal 58480 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 XVssBJ#01M7olcSaV(fF*fAI6)u)>;0 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff new file mode 100644 index 0000000000000000000000000000000000000000..c205e6fd3cae5dbfd991d499c7495c9228a804c3 GIT binary patch literal 58556 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 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-icon-black-1.png b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-icon-black-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cd702885b45d555982a9207ad95cb571016e437b GIT binary patch literal 15510 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 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-white-32.png b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/codemr-white-32.png new file mode 100644 index 0000000000000000000000000000000000000000..0201baefade8077c9e1e2a1fb4871d9e93bb471e GIT binary patch literal 1254 zcmV+_)5rR-bL6Hgy3Xl>B@e)fxkyMCRhmee-h*%*nHeeaY z9`DZX>^$zBd++yA#72p|JG&c&BTX@*Gv}OdzN_!v5f}oEMq}%!l>3G6&%pC`JLk3$ zkqkVq?U)yhF;}g%^{J_;WKd1fkHE~b*=!!%vSrJ0Ddlrg%2^@AB!H2%_XPj~P!Lg* zh%P(lzRR-gT(w%gB7~q}io6R^6iq9o-nZ5+Ff;LhAR@BXE-0l=udJ-h3~kKJUZ>M} z*%)(i7~?KM*cfvu>vUdWW^YjQkt9h@I_IK$HQos4T$Jbe8_ZlOHJ_WC3-UaFi-@xO zWxfs~%F;AFH8(dG^bC-u>1)op&iyuDhjXqI$MNf3&7&wfY^}ZVf0?ht7*lVxT94gj ze(l<|idO3LVT6dNaMni7+7=P%VcykBeNnI1M*+YGfT^jeV}204ILIP(*50(veOna8 z&!qJt0E|>Bd!+9_H>ecV|o^=Yfsn(S9yy(0%u99=km2o5xNFqx6XjK7h9X7zW z>FEc2-``foA?8#v^I{*ZNztcG-7q#bwqHuQvy8*QqGaYvWvdl{u-3|90|Y@ZE`;dW zUS?+J+`KG`;#X$w^mGRh3~+SY2+u1&e=u{*%)j_qmR%ShAHNLX$*x3TAprhi=D-+p zFbIN?5?uix1#l%vlAB{=W6PfB?d?W%&ixU`@dW@tp6BlnZ9aJs5vOVTHUOk)`n+>) ziJ4o>9QC+b&bb@ycKgVh?uR|5Am@30>c2E$7|t4FHth$-n5!!*D>L)+^CLx3d{Z`B z??j&G9|1tC)q31oyWB&iu3=881r|d(KuAA)jX}#XM>urLn(C{0OB}4>YQ6$e_j;D zxt_afv)O#a81p;d?$HMT5I37gopX(016XVSjN|xVtyc4tQeQIP-c^$%dAMW|17R2* z(^~(yzL2!mpA2ixyw*ac-UWax%U&&tVlIlJr%TO&+b5eij<++jOw;tRv-Z}#1X!#1 zO0={z&CFwIn(pK-Cn3|GOa^q zj@NE^$O{ZKecx}Cd6bS=W*${a9hXw>lTr@#mus!{l~R`{CMM1cA#5++zonN?TEWqf Q1^@s607*qoM6N<$f?TRlegFUf literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/default-avatar.png b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/default-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9fa88471a83781acf0c00784d5b4bad2ca487b GIT binary patch literal 2864 zcmW-j2UL^E7RNsVNa(R3EDs{E;vy)kf(p{hO4(f=^5CI7P!!!&Tv3qfDgp^z2@rZq zA=E&qp(H_qpaDce&U0gv&KxlE3GC={^K0?*Bfdpn@U|u&5K@?D0DU-N}QX`)LrgH2^{A zEeMK=g`i!q@x&bn+ILhLdBhEZq#^g;Jb(H0X|bpnmtRm+SX44SJ(HJTI5sxEwzl@_ z)xh)T-5Hr#TU%Qdl~r8sI}T@Pcng&CS%> zT1rbxYfUYsth}<8Qb(z)r+`u4(A3miS65$G-_Y3D)X>maN-8fUm6hNKRaNBb>YCyb zd__f7O-(Jaw5*`8xUH?7SV|(5RpjOsRDzR{Yw!djgTWvWOUuhE@r2Tb#wJh+)M{*M z!r_THJfWFNrP1iEt!?$7dQ)>-TU&NcUQTX)3s`Dz@95~r&dtxt$)nL|*zDY_?A-Qt zS_uwMqk~`+6cuB$z}~`~yn@WE90sE!6PuHP%}&qAO3%R7)YiQl8JV1%tgCD2c-F~e zc76Exv8jnVH#axGupkzTOG@zHzI}^{iHVJkjf;yzp-^ZvIzB!=At50#F)=AADLFYg zB_$;_HTB7pCr_U~O-oC|U@+zyKlx9zfymR|iM|nSX=^_hNQ+bv*}O>F)07>3Q)2DEyMeV)gd+ z_VxAk_xHa7P8t|^{rWZV1Dnkr0-gX)8V2IOc?)a-jP(w18W{yHdH?{B%5D4by0mTKOQ1}TrcyUoA5-lw)0jkT(%PT7@ zpFe+IU0nq>USD6ANF*B@8(+SB+1%U&X5QZ3-r3pN-QE5A^()|imifzG2$HLIakTS{ zZ>g;1cShYneyY;rmD| zR)yt|qtlYfbpLSAY+%t=sK3{-q&v8`Nvgr>kx$6!$Qyph@r^1)f?Kxp$QhL9P zR`8nA{$Zju#&>M5lAirvSyu!je%i7qJ9W(-1umC!;e>`#0!Js^PZo96G)cCR>~E$O zu4m^@S4ecw)pAyBA>V^5!p6M}dJ=s!5X%(%JyWb0GXh;3VW|uA{f2jTZtB%6^tx-}ODGdcb-AGb1hdzaQC%zwUgQWyTV-#oUlvO%Iq#<#)s4Igu!V<$T+

    *?EPk9lm`;XXd9~ zaIAjOWXqT++!j8H)Gtn)2#Tmw>rePaU4GqV$7JjK`E?Ya zQ26lEa&lcFg?({6H658CjBrHlgiN#1ie)ASuk*)SN@gF`AZ^e-);fbUQdp|6!vZ#$|3s%P@?xZ1_K-N1x3~BnKgytM!yw zTKBfey^nHJzQmo_pg`nL_MJv)H>Gr&>8>Gfc($h2;$f6&)sn!)%>+)MJKd5e?3nl7 zmJRk8XM3qQ&aP4`!^`y1!cD_KuF5c}1$SRdU7u%{gyA8}h6!6$Fo7ZH7f``n||U8_XLb`PWqSwpRo6k(j#;av4MfL8S7@ZREes6uMQsd3@<~VjixS$JSr%Eq}AH270sI zV7Yb=@j6EHgPEDxML)0Lit{IDnue`hd0wmr8f|OgKLg3|C`zbJXD~AE$AhUakp8w= z-zEivX%`1>nx2!=eLd3u%qExP#ky*$`P5Q_P zT@LRHS5)q;6pGnu;oM-*tk8Wkp0ZJHvwypVts=CJVEarEyt5d!;Iq4kzWM>IWR@_it}|tE->hi{|d`Xr8)>q+W*8w>O{qaRaF|_;X3L zbsO2IR`Tar^!o0@Wy`?a4usX>g-3J2QBg+|<^wQ7fyREjQ9gS+f~&~6>m3kah3E*^ zkFW2u-El8ot^|Dp?H=bOO`McjdS6dtzj7qfE~ ZLgvRUj{Gpa175q3%P($@6np=;{{!!q3-15` literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/favicon.ico b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7482a653daf1130d6dea4ba9a92259a8cf15c87a GIT binary patch literal 1150 zcmeH_F-`(e6h+^6Y={&PBZU=}F`+kc5tPKZ13H6^p@Xmhw<9GbE<<}0s3=f47yeED zB<=v-${Wq#=&@RX63=ee@lalIfsEBhb5 zC_QWKxW)+k?i;+XjI@1s?YN#1<@0}YeuZvETAp{6)sE{9@dLMR-X2&UQwsn9 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/loading-bubbles.svg b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/loading-bubbles.svg new file mode 100644 index 0000000..4020b4d --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/loading-bubbles.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/mask.png b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..429360d5ce730f002b7413fdb94bcd261339b5ce GIT binary patch literal 756 zcmeAS@N?(olHy`uVBq!ia0vp^0YEIv!NkD8cyyD`Js^j(z$3Dlfq`2Xgc%uT&5-~K zDkOUZ`7$u%&R}3D?qgv1b%ueV3kcwML zKmLP({*A-*E2LeiU=QJ1RAk@^Je8B|IkoT7jCe!ITtr_Iw7T7H-mN|a>_~Iq6)cxmOxaCz}U%#Ui=s2K3N3I^^Y%vgEy)dEq$tzzSg&VCE z-hNH8D(cxBVu|TZ(-bt7gnr7EDXw`FXuQACea6q3EX)??i)Ss{wNCy>i$Lu4wXeJG zt5is|ZI6GmcmLtk$Y+utw&ikeyY?(*od6RG}N|3)b--Fx0`gf zzb;_}x%SBnuxnk_#RT?9>t``*iRooAcc!mZnAfW+aiSt1qKtFX^3=I|_~e*B|L0l2 zpZ(T=$M^C9X3f)^UR!0a4SyS4G4HvFZzGFS$8JvPnb8pYyQ0%A4xY&>OYj9^0NMc%^60)#}<5!Gm85<1XFVdQ&MBb@031k3nE(I) literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/new_logo.png b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/new_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2192bdde5cb354dd4db5f1b7d55de774c3a062 GIT binary patch literal 3557 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 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/sidebar-5.jpg b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/img/sidebar-5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7471ab8e2fef9a071b93321963660f9fa6960714 GIT binary patch literal 280836 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%0A~`8*jGY*w~u8LamVc4oyy^`HHqR$qaN_oy<_ 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%0DuDx*(!!P26!%nXS^Y2jA>(y?t(=xAKbRL~;;| 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
    (rZcrY@enMMxTMbaQQR$2$pm%`uegL-%Gj)9hoS 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

    o^1?)&%uv7A^X2@f|Q0QPLF^^? zph1O{l3~P<_sUVX-(d17;jS+f{@TU4t90ukO_Hcttk97W&Hj+{cy+P`@Lk{}=uS7n zHil+6=&4C`(O%}gi5lefgMo&dF$6GWsC4rexlRPS08Lj_1BFH9-!@WE3h*7%vs{@z~qi>LIe9e{snTF;*8r1`MO;mf1$s z4BGf@Z5j1Uu8k~dAaGSR+aWNR`QCMRsU7P2!be{GfbUTEUWP5MYdX)r#)ErptH)UGJJYV?)YKSJ>_8Xh=D{sFT= z-Oj3<6ZP&A=&h(`p2wHS(6XA?Tr$Pg;yW8imoc{ftALY*Pr+JKCK~O<5Zufi%S(rO zs%E^mu#-)6du_2Z{pj?(KMvfJ36sw#xjvsYCWK~FiAK%7=ASblmK6F8iZ?slty~`G zzuOc+$_+-mKDeO35d9Hpo2Kj77oBlv*zePra;^O}_ATt?tGb^e%YlSty69-CZ@0-} zP35p_$Wj;;?Y#yW%(rF^eXo#i@>$Jd1*PUR*1R>RYUo)uw8RZ@FMWC79ouJMZ?khK znxYa5>;T-bUTcKe&OEQ2`lI^F9QA9l8HSs?x!de!|7N_*W841g1GjfR3QHsl2nZpp zO|UiS4(|()TU|D!+dfh@Q~3f=6ztx#JTFmg5&hd{-w?X)b;LF9Rw}4SXm9-Zcboiq z^*EXds?6yq;u_Z$n#8O%GrtB|w~0M?o5wAXwx(*~7ν5qic=WYF=sJwGlHV7A>F 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�+%{J4bcp~7@ubq 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 ZS2=0^r}3h@>1P;)1e0HJl(6x+|Jk!)inss( literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js new file mode 100644 index 0000000..cf05f1b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js @@ -0,0 +1,502 @@ +!function ($) { + + /* CHECKBOX PUBLIC CLASS DEFINITION + * ============================== */ + + var Checkbox = function (element, options) { + this.init(element, options); + } + + Checkbox.prototype = { + + constructor: Checkbox + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.checkbox.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.checkbox'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checked = $el.prop(ch) + , e = $.Event('toggle') + + if ($el.prop('disabled') == false) { + $parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.prop(ch, ch); + $el.trigger(e).trigger('change'); + } + } + + , setCheck: function (option) { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checkAction = option == 'check' ? true : false + , e = $.Event(option) + + $parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e).trigger('change'); + } + + } + + + /* CHECKBOX PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.checkbox + + $.fn.checkbox = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('checkbox') + , options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.checkbox.defaults = { + template: '' + } + + + /* CHECKBOX NO CONFLICT + * ================== */ + + $.fn.checkbox.noConflict = function () { + $.fn.checkbox = old; + return this; + } + + + /* CHECKBOX DATA-API + * =============== */ + + $(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) { + var $checkbox = $(e.target); + if (e.target.tagName != "A") { + e && e.preventDefault() && e.stopPropagation(); + if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox'); + $checkbox.find(':checkbox').checkbox('toggle'); + } + }); + + $(function () { + $('[data-toggle="checkbox"]').each(function () { + var $checkbox = $(this); + $checkbox.checkbox(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================= + * flatui-radio v0.0.3 + * ============================================================ */ + +!function ($) { + + /* RADIO PUBLIC CLASS DEFINITION + * ============================== */ + + var Radio = function (element, options) { + this.init(element, options); + } + + Radio.prototype = { + + constructor: Radio + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.radio.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.radio'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , checked = $el.prop(ch) + , $parent = $el.closest('.radio') + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]') + , e = $.Event('toggle') + + if ($el.prop(d) == false) { + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + if ($el.prop(d) == false) { + $parent.removeClass(ch) && $el.removeAttr(ch).trigger('change'); + } + }); + + if (checked == false) $parent.addClass(ch) && $el.prop(ch, true); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + } + + , setCheck: function (option) { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.radio') + , checkAction = option == 'check' ? true : false + , checked = $el.prop(ch) + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]') + , e = $.Event(option) + + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + $parent.removeClass(ch) && $el.removeAttr(ch); + }); + + $parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + + } + + + /* RADIO PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.radio + + $.fn.radio = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('radio') + , options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('radio', (data = new Radio(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.radio.defaults = { + template: '' + } + + + /* RADIO NO CONFLICT + * ================== */ + + $.fn.radio.noConflict = function () { + $.fn.radio = old; + return this; + } + + + /* RADIO DATA-API + * =============== */ + + $(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) { + var $radio = $(e.target); + e && e.preventDefault() && e.stopPropagation(); + if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio'); + $radio.find(':radio').radio('toggle'); + }); + + $(function () { + $('[data-toggle="radio"]').each(function () { + var $radio = $(this); + $radio.radio(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ + +!function ($) { + "use strict"; + + $.fn['bootstrapSwitch'] = function (method) { + var methods = { + init: function () { + return this.each(function () { + var $element = $(this) + , $div + , $switchLeft + , $switchRight + , $label + , myClasses = "" + , classes = $element.attr('class') + , color + , moving + , onLabel = "ON" + , offLabel = "OFF" + , icon = false; + + $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { + if (classes.indexOf(el) >= 0) + myClasses = el; + }); + + $element.addClass('has-switch'); + + if ($element.data('on') !== undefined) + color = "switch-" + $element.data('on'); + + if ($element.data('on-label') !== undefined) + onLabel = $element.data('on-label'); + + if ($element.data('off-label') !== undefined) + offLabel = $element.data('off-label'); + + if ($element.data('icon') !== undefined) + icon = $element.data('icon'); + + $switchLeft = $('') + .addClass("switch-left") + .addClass(myClasses) + .addClass(color) + .html(onLabel); + + color = ''; + if ($element.data('off') !== undefined) + color = "switch-" + $element.data('off'); + + $switchRight = $('') + .addClass("switch-right") + .addClass(myClasses) + .addClass(color) + .html(offLabel); + + $label = $('

    ')).parent().data('animated', false); + + if ($element.data('animated') !== false) + $div.addClass('switch-animate').data('animated', true); + + $div + .append($switchLeft) + .append($label) + .append($switchRight); + + $element.find('>div').addClass( + $element.find('input').is(':checked') ? 'switch-on' : 'switch-off' + ); + + if ($element.find('input').is(':disabled')) + $(this).addClass('deactivate'); + + var changeStatus = function ($this) { + $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click'); + }; + + $element.on('keydown', function (e) { + if (e.keyCode === 32) { + e.stopImmediatePropagation(); + e.preventDefault(); + changeStatus($(e.target).find('span:first')); + } + }); + + $switchLeft.on('click', function (e) { + changeStatus($(this)); + }); + + $switchRight.on('click', function (e) { + changeStatus($(this)); + }); + + $element.find('input').on('change', function (e) { + var $this = $(this) + , $element = $this.parent() + , thisState = $this.is(':checked') + , state = $element.is('.switch-off'); + + e.preventDefault(); + + $element.css('left', ''); + + if (state === thisState) { + + if (thisState) + $element.removeClass('switch-off').addClass('switch-on'); + else $element.removeClass('switch-on').addClass('switch-off'); + + if ($element.data('animated') !== false) + $element.addClass("switch-animate"); + + $element.parent().trigger('switch-change', {'el': $this, 'value': thisState}) + } + }); + + $element.find('label').on('mousedown touchstart', function (e) { + var $this = $(this); + moving = false; + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.closest('div').removeClass('switch-animate'); + + if ($this.closest('.has-switch').is('.deactivate')) + $this.unbind('click'); + else { + $this.on('mousemove touchmove', function (e) { + var $element = $(this).closest('.switch') + , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left + , percent = (relativeX / $element.width()) * 100 + , left = 25 + , right = 75; + + moving = true; + + if (percent < left) + percent = left; + else if (percent > right) + percent = right; + + $element.find('>div').css('left', (percent - right) + "%") + }); + + $this.on('click touchend', function (e) { + var $this = $(this) + , $target = $(e.target) + , $myCheckBox = $target.siblings('input'); + + e.stopImmediatePropagation(); + e.preventDefault(); + + $this.unbind('mouseleave'); + + if (moving) + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)); + else $myCheckBox.prop("checked", !$myCheckBox.is(":checked")); + + moving = false; + $myCheckBox.trigger('change'); + }); + + $this.on('mouseleave', function (e) { + var $this = $(this) + , $myCheckBox = $this.siblings('input'); + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.unbind('mouseleave'); + $this.trigger('mouseup'); + + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change'); + }); + + $this.on('mouseup', function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + + $(this).unbind('mousemove'); + }); + } + }); + } + ); + }, + toggleActivation: function () { + $(this).toggleClass('deactivate'); + }, + isActive: function () { + return !$(this).hasClass('deactivate'); + }, + setActive: function (active) { + if (active) + $(this).removeClass('deactivate'); + else $(this).addClass('deactivate'); + }, + toggleState: function (skipOnChange) { + var $input = $(this).find('input:checkbox'); + $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange); + }, + setState: function (value, skipOnChange) { + $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange); + }, + status: function () { + return $(this).find('input:checkbox').is(':checked'); + }, + destroy: function () { + var $div = $(this).find('div') + , $checkbox; + + $div.find(':not(input:checkbox)').remove(); + + $checkbox = $div.children(); + $checkbox.unwrap().unwrap(); + + $checkbox.unbind('change'); + + return $checkbox; + } + }; + + if (methods[method]) + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + else if (typeof method === 'object' || !method) + return methods.init.apply(this, arguments); + else + $.error('Method ' + method + ' does not exist!'); + }; +}(jQuery); + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-notify.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-notify.js new file mode 100644 index 0000000..f2f0c74 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-notify.js @@ -0,0 +1,404 @@ +/* + + + + Creative Tim Modifications + + Lines: 239, 240 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically + Line:242 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon. + + + + +*/ + + +/* +* Project: Bootstrap Notify = v3.1.5 +* Description: Turns standard Bootstrap alerts into "Growl-like" notifications. +* Author: Mouse0270 aka Robert McIntosh +* License: MIT License +* Website: https://github.com/mouse0270/bootstrap-growl +*/ + +/* global define:false, require: false, jQuery:false */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + // Create the defaults once + var defaults = { + element: 'body', + position: null, + type: "info", + allow_dismiss: true, + allow_duplicates: true, + newest_on_top: false, + showProgressbar: false, + placement: { + from: "top", + align: "right" + }, + offset: 20, + spacing: 10, + z_index: 1031, + delay: 5000, + timer: 1000, + url_target: '_blank', + mouse_over: null, + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + onShow: null, + onShown: null, + onClose: null, + onClosed: null, + icon_type: 'class', + template: '' + }; + + String.format = function () { + var str = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + str = str.replace(RegExp("\\{" + (i - 1) + "\\}", "gm"), arguments[i]); + } + return str; + }; + + function isDuplicateNotification(notification) { + var isDupe = false; + + $('[data-notify="container"]').each(function (i, el) { + var $el = $(el); + var title = $el.find('[data-notify="title"]').text().trim(); + var message = $el.find('[data-notify="message"]').html().trim(); + + // The input string might be different than the actual parsed HTML string! + // (
    vs
    for example) + // So we have to force-parse this as HTML here! + var isSameTitle = title === $("
    " + notification.settings.content.title + "
    ").html().trim(); + var isSameMsg = message === $("
    " + notification.settings.content.message + "
    ").html().trim(); + var isSameType = $el.hasClass('alert-' + notification.settings.type); + + if (isSameTitle && isSameMsg && isSameType) { + //we found the dupe. Set the var and stop checking. + isDupe = true; + } + return !isDupe; + }); + + return isDupe; + } + + function Notify(element, content, options) { + // Setup Content of Notify + var contentObj = { + content: { + message: typeof content === 'object' ? content.message : content, + title: content.title ? content.title : '', + icon: content.icon ? content.icon : '', + url: content.url ? content.url : '#', + target: content.target ? content.target : '-' + } + }; + + options = $.extend(true, {}, contentObj, options); + this.settings = $.extend(true, {}, defaults, options); + this._defaults = defaults; + if (this.settings.content.target === "-") { + this.settings.content.target = this.settings.url_target; + } + this.animations = { + start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart', + end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend' + }; + + if (typeof this.settings.offset === 'number') { + this.settings.offset = { + x: this.settings.offset, + y: this.settings.offset + }; + } + + //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing + if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) { + this.init(); + } + } + + $.extend(Notify.prototype, { + init: function () { + var self = this; + + this.buildNotify(); + if (this.settings.content.icon) { + this.setIcon(); + } + if (this.settings.content.url != "#") { + this.styleURL(); + } + this.styleDismiss(); + this.placement(); + this.bind(); + + this.notify = { + $ele: this.$ele, + update: function (command, update) { + var commands = {}; + if (typeof command === "string") { + commands[command] = update; + } else { + commands = command; + } + for (var cmd in commands) { + switch (cmd) { + case "type": + this.$ele.removeClass('alert-' + self.settings.type); + this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type); + self.settings.type = commands[cmd]; + this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]); + break; + case "icon": + var $icon = this.$ele.find('[data-notify="icon"]'); + if (self.settings.icon_type.toLowerCase() === 'class') { + $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]); + } else { + if (!$icon.is('img')) { + $icon.find('img'); + } + $icon.attr('src', commands[cmd]); + } + break; + case "progress": + var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100)); + this.$ele.data('notify-delay', newDelay); + this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%'); + break; + case "url": + this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]); + break; + case "target": + this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]); + break; + default: + this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]); + } + } + var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y); + self.reposition(posX); + }, + close: function () { + self.close(); + } + }; + + }, + buildNotify: function () { + var content = this.settings.content; + this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target)); + this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align); + if (!this.settings.allow_dismiss) { + this.$ele.find('[data-notify="dismiss"]').css('display', 'none'); + } + if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) { + this.$ele.find('[data-notify="progressbar"]').remove(); + } + }, + setIcon: function () { + + this.$ele.addClass('alert-with-icon'); + + if (this.settings.icon_type.toLowerCase() === 'class') { + this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon); + } else { + if (this.$ele.find('[data-notify="icon"]').is('img')) { + this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon); + } else { + this.$ele.find('[data-notify="icon"]').append('Notify Icon'); + } + } + }, + styleDismiss: function () { + this.$ele.find('[data-notify="dismiss"]').css({ + position: 'absolute', + right: '10px', + top: '50%', + marginTop: '-13px', + zIndex: this.settings.z_index + 2 + }); + }, + styleURL: function () { + this.$ele.find('[data-notify="url"]').css({ + backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)', + height: '100%', + left: 0, + position: 'absolute', + top: 0, + width: '100%', + zIndex: this.settings.z_index + 1 + }); + }, + placement: function () { + var self = this, + offsetAmt = this.settings.offset.y, + css = { + display: 'inline-block', + margin: '0px auto', + position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'), + transition: 'all .5s ease-in-out', + zIndex: this.settings.z_index + }, + hasAnimation = false, + settings = this.settings; + + $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { + offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing)); + }); + if (this.settings.newest_on_top === true) { + offsetAmt = this.settings.offset.y; + } + css[this.settings.placement.from] = offsetAmt + 'px'; + + switch (this.settings.placement.align) { + case "left": + case "right": + css[this.settings.placement.align] = this.settings.offset.x + 'px'; + break; + case "center": + css.left = 0; + css.right = 0; + break; + } + this.$ele.css(css).addClass(this.settings.animate.enter); + $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function (index, prefix) { + self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1; + }); + + $(this.settings.element).append(this.$ele); + + if (this.settings.newest_on_top === true) { + offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight(); + this.reposition(offsetAmt); + } + + if ($.isFunction(self.settings.onShow)) { + self.settings.onShow.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + } + }, 600); + }, + bind: function () { + var self = this; + + this.$ele.find('[data-notify="dismiss"]').on('click', function () { + self.close(); + }); + + this.$ele.mouseover(function () { + $(this).data('data-hover', "true"); + }).mouseout(function () { + $(this).data('data-hover', "false"); + }); + this.$ele.data('data-hover', "false"); + + if (this.settings.delay > 0) { + self.$ele.data('notify-delay', self.settings.delay); + var timer = setInterval(function () { + var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer; + if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") { + var percent = ((self.settings.delay - delay) / self.settings.delay) * 100; + self.$ele.data('notify-delay', delay); + self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%'); + } + if (delay <= -(self.settings.timer)) { + clearInterval(timer); + self.close(); + } + }, self.settings.timer); + } + }, + close: function () { + var self = this, + posX = parseInt(this.$ele.css(this.settings.placement.from)), + hasAnimation = false; + + this.$ele.data('closing', 'true').addClass(this.settings.animate.exit); + self.reposition(posX); + + if ($.isFunction(self.settings.onClose)) { + self.settings.onClose.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + $(this).remove(); + if ($.isFunction(self.settings.onClosed)) { + self.settings.onClosed.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + self.$ele.remove(); + if (self.settings.onClosed) { + self.settings.onClosed(self.$ele); + } + } + }, 600); + }, + reposition: function (posX) { + var self = this, + notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])', + $elements = this.$ele.nextAll(notifies); + if (this.settings.newest_on_top === true) { + $elements = this.$ele.prevAll(notifies); + } + $elements.each(function () { + $(this).css(self.settings.placement.from, posX); + posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight(); + }); + } + }); + + $.notify = function (content, options) { + var plugin = new Notify(this, content, options); + return plugin.notify; + }; + $.notifyDefaults = function (options) { + defaults = $.extend(true, {}, defaults, options); + return defaults; + }; + $.notifyClose = function (command) { + if (typeof command === "undefined" || command === "all") { + $('[data-notify]').find('[data-notify="dismiss"]').trigger('click'); + } else { + $('[data-notify-position="' + command + '"]').find('[data-notify="dismiss"]').trigger('click'); + } + }; + +})); diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-select.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-select.js new file mode 100644 index 0000000..a9ee735 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap-select.js @@ -0,0 +1,438 @@ +!function($) { + var Selectpicker = function(element, options, e) { + if (e ) { + e.stopPropagation(); + e.preventDefault(); + } + this.$element = $(element); + this.$newElement = null; + this.button = null; + + //Merge defaults, options and data-attributes to make our options + this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options); + + //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute + if(this.options.title==null) + this.options.title = this.$element.attr('title'); + + //Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.init(); + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function (e) { + var _this = this; + this.$element.hide(); + this.multiple = this.$element.prop('multiple'); + + + var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : ''; + var id = this.$element.attr('id'); + this.$element.after( this.createView() ); + this.$newElement = this.$element.next('.select'); + var select = this.$newElement; + var menu = this.$newElement.find('.dropdown-menu'); + var menuArrow = this.$newElement.find('.dropdown-arrow'); + var menuA = menu.find('li > a'); + var liHeight = select.addClass('open').find('.dropdown-menu li > a').outerHeight(); + select.removeClass('open'); + var divHeight = menu.find('li .divider').outerHeight(true); + var selectOffset_top = this.$newElement.offset().top; + var size = 0; + var menuHeight = 0; + var selectHeight = this.$newElement.outerHeight(); + this.button = this.$newElement.find('> button'); + if (id !== undefined) { + this.button.attr('id', id); + $('label[for="' + id + '"]').click(function(){ select.find('button#'+id).focus(); }) + } + for (var i = 0; i < classList.length; i++) { + if(classList[i] != 'selectpicker') { + this.$newElement.addClass(classList[i]); + } + } + //If we are multiple, then add the show-tick class by default + if(this.multiple) { + this.$newElement.addClass('select-multiple'); + } + this.button.addClass(this.options.style); + menu.addClass(this.options.menuStyle); + menuArrow.addClass(function() { + if (_this.options.menuStyle) { + return _this.options.menuStyle.replace('dropdown-', 'dropdown-arrow-'); + } + }); + this.checkDisabled(); + this.checkTabIndex(); + this.clickListener(); + var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width')); + if (this.options.size == 'auto') { + + // Creative Tim Changes: We changed the regular function made in bootstrap-select with this function so the getSize() will not be triggered one million times per second while you scroll. + + var getSize = debounce(function() { + var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop(); + var windowHeight = $(window).innerHeight(); + var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2; + var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras; + menuHeight = selectOffset_bot; + if (select.hasClass('dropup')) { + menuHeight = selectOffset_top_scroll - menuExtras; + } + //limit menuHeight to 300px to have a smooth transition with cubic bezier on dropdown + if(menuHeight >= 300){ + menuHeight = 300; + } + + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : liHeight * 3 + 'px'}); + + }, 50); + + getSize; + $(window).on('scroll', getSize); + $(window).on('resize', getSize); + + if (window.MutationObserver) { + new MutationObserver(getSize).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', getSize); + } + } else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) { + var optIndex = menu.find("li > *").filter(':not(.divider)').slice(0,this.options.size).last().parent().index(); + var divLength = menu.find("li").slice(0,optIndex + 1).find('.divider').length; + menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding; + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'scroll'}); + //console.log('sunt in if'); + } + + // Listen for updates to the DOM and re render... (Use Mutation Observer when availiable) + if (window.MutationObserver) { + new MutationObserver($.proxy(this.reloadLi, this)).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this)); + } + + this.render(); + }, + + createDropdown: function() { + var drop = + "
    " + + "" + + "" + + "" + + "
    "; + + return $(drop); + }, + + + createView: function() { + var $drop = this.createDropdown(); + var $li = this.createLi(); + $drop.find('ul').append($li); + return $drop; + }, + + reloadLi: function() { + //Remove all children. + this.destroyLi(); + //Re build + $li = this.createLi(); + this.$newElement.find('ul').append( $li ); + //render view + this.render(); + }, + + destroyLi:function() { + this.$newElement.find('li').remove(); + }, + + createLi: function() { + + var _this = this; + var _li = []; + var _liA = []; + var _liHtml = ''; + + this.$element.find('option').each(function(){ + _li.push($(this).text()); + }); + + this.$element.find('option').each(function(index) { + //Get the class and text for the option + var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : ''; + var text = $(this).text(); + var subtext = $(this).data('subtext') !== undefined ? ''+$(this).data('subtext')+'' : ''; + + //Append any subtext to the main text. + text+=subtext; + + if ($(this).parent().is('optgroup') && $(this).data('divider') != true) { + if ($(this).index() == 0) { + //Get the opt group label + var label = $(this).parent().attr('label'); + var labelSubtext = $(this).parent().data('subtext') !== undefined ? ''+$(this).parent().data('subtext')+'' : ''; + label += labelSubtext; + + if ($(this)[0].index != 0) { + _liA.push( + '
    '+ + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass ) + ); + } else { + _liA.push( + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass )); + } + } else { + _liA.push( _this.createA(text, "opt " + optionClass ) ); + } + } else if ($(this).data('divider') == true) { + _liA.push('
    '); + } else if ($(this).data('hidden') == true) { + _liA.push(''); + } else { + _liA.push( _this.createA(text, optionClass ) ); + } + }); + + if (_li.length > 0) { + for (var i = 0; i < _li.length; i++) { + var $option = this.$element.find('option').eq(i); + _liHtml += "
  • " + _liA[i] + "
  • "; + } + } + + //If we dont have a selected item, and we dont have a title, select the first element so something is set in the button + if(this.$element.find('option:selected').length==0 && !_this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return $(_liHtml); + }, + + createA:function(test, classes) { + return '' + + '' + test + '' + + ''; + + }, + + render:function() { + var _this = this; + + //Set width of select + if (this.options.width == 'auto') { + var ulWidth = this.$newElement.find('.dropdown-menu').css('width'); + this.$newElement.css('width',ulWidth); + } else if (this.options.width && this.options.width != 'auto') { + this.$newElement.css('width',this.options.width); + } + + //Update the LI to match the SELECT + this.$element.find('option').each(function(index) { + _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') ); + _this.setSelected(index, $(this).is(':selected') ); + }); + + + + var selectedItems = this.$element.find('option:selected').map(function(index,value) { + if($(this).attr('title')!=undefined) { + return $(this).attr('title'); + } else { + return $(this).text(); + } + }).toArray(); + + //Convert all the values into a comma delimited string + var title = selectedItems.join(", "); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) { + var max = _this.options.selectedTextFormat.split(">"); + if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) { + title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected'; + } + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if(!title) { + title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText; + } + + this.$element.next('.select').find('.filter-option').html( title ); + }, + + + + setSelected:function(index, selected) { + if(selected) { + this.$newElement.find('li').eq(index).addClass('selected'); + } else { + this.$newElement.find('li').eq(index).removeClass('selected'); + } + }, + + setDisabled:function(index, disabled) { + if(disabled) { + this.$newElement.find('li').eq(index).addClass('disabled'); + } else { + this.$newElement.find('li').eq(index).removeClass('disabled'); + } + }, + + checkDisabled: function() { + if (this.$element.is(':disabled')) { + this.button.addClass('disabled'); + this.button.click(function(e) { + e.preventDefault(); + }); + } + }, + + checkTabIndex: function() { + if (this.$element.is('[tabindex]')) { + var tabindex = this.$element.attr("tabindex"); + this.button.attr('tabindex', tabindex); + } + }, + + clickListener: function() { + var _this = this; + + $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); + + + + this.$newElement.on('click', 'li a', function(e){ + var clickedIndex = $(this).parent().index(), + $this = $(this).parent(), + $select = $this.parents('.select'); + + + //Dont close on multi choice menu + if(_this.multiple) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Dont run if we have been disabled + if ($select.prev('select').not(':disabled') && !$(this).parent().hasClass('disabled')){ + //Deselect all others if not multi select box + if (!_this.multiple) { + $select.prev('select').find('option').removeAttr('selected'); + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + //Else toggle the one we have chosen if we are multi selet. + else { + var selected = $select.prev('select').find('option').eq(clickedIndex).prop('selected'); + + if(selected) { + $select.prev('select').find('option').eq(clickedIndex).removeAttr('selected'); + } else { + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + } + + + $select.find('.filter-option').html($this.text()); + $select.find('button').focus(); + + // Trigger select 'change' + $select.prev('select').trigger('change'); + } + + }); + + this.$newElement.on('click', 'li.disabled a, li dt, li .divider', function(e) { + e.preventDefault(); + e.stopPropagation(); + $select = $(this).parent().parents('.select'); + $select.find('button').focus(); + }); + + this.$element.on('change', function(e) { + _this.render(); + }); + }, + + val:function(value) { + + if(value!=undefined) { + this.$element.val( value ); + + this.$element.trigger('change'); + return this.$element; + } else { + return this.$element.val(); + } + } + + }; + + $.fn.selectpicker = function(option, event) { + //get the args of the outer function.. + var args = arguments; + var value; + var chain = this.each(function () { + var $this = $(this), + data = $this.data('selectpicker'), + options = typeof option == 'object' && option; + + if (!data) { + $this.data('selectpicker', (data = new Selectpicker(this, options, event))); + } else { + for(var i in option) { + data[i]=option[i]; + } + } + + if (typeof option == 'string') { + //Copy the value of option, as once we shift the arguments + //it also shifts the value of option. + property = option; + if(data[property] instanceof Function) { + [].shift.apply(args); + value = data[property].apply(data, args); + } else { + value = data[property]; + } + } + }); + + if(value!=undefined) { + return value; + } else { + return chain; + } + }; + + $.fn.selectpicker.defaults = { + style: null, + size: 'auto', + title: null, + selectedTextFormat : 'values', + noneSelectedText : 'Nothing selected', + width: null, + menuStyle: null, + toggleSize: null + } + +}(window.jQuery); diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap.min.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/chartist.min.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/chartist.min.js new file mode 100644 index 0000000..b69e484 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/chartist.min.js @@ -0,0 +1,9 @@ +/* Chartist.js 0.9.4 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ + +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.Chartist=b()}):"object"==typeof exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.9.4"};return function(a,b,c){"use strict";c.noop=function(a){return a},c.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},c.extend=function(a){a=a||{};var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){for(var d in b)"object"!=typeof b[d]||null===b[d]||b[d]instanceof Array?a[d]=b[d]:a[d]=c.extend({},a[d],b[d])}),a},c.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},c.stripUnit=function(a){return"string"==typeof a&&(a=a.replace(/[^0-9\+-\.]/g,"")),+a},c.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},c.querySelector=function(a){return a instanceof Node?a:b.querySelector(a)},c.times=function(a){return Array.apply(null,new Array(a))},c.sum=function(a,b){return a+(b?b:0)},c.mapMultiply=function(a){return function(b){return b*a}},c.mapAdd=function(a){return function(b){return b+a}},c.serialMap=function(a,b){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return c.times(e).forEach(function(c,e){var f=a.map(function(a){return a[e]});d[e]=b.apply(null,f)}),d},c.roundWithPrecision=function(a,b){var d=Math.pow(10,b||c.precision);return Math.round(a*d)/d},c.precision=8,c.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},c.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,b,c.escapingMap[b])},a))},c.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,c.escapingMap[b],b)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(b){}return a},c.createSvg=function(a,b,d,e){var f;return b=b||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS("http://www.w3.org/2000/xmlns/",c.xmlNs.prefix)}).forEach(function(b){a.removeChild(b)}),f=new c.Svg("svg").attr({width:b,height:d}).addClass(e).attr({style:"width: "+b+"; height: "+d+";"}),a.appendChild(f._node),f},c.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;bf.high&&(f.high=c),h&&ck,m=e?c.rho(j.range):0;if(e&&c.projectLength(a,1,j)>=d)j.step=1;else if(e&&m=d)j.step=m;else for(;;){if(l&&c.projectLength(a,j.step,j)<=d)j.step*=2;else{if(l||!(c.projectLength(a,j.step/2,j)>=d))break;if(j.step/=2,e&&j.step%1!==0){j.step*=2;break}}if(i++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}for(g=j.min,h=j.max;g+j.step<=j.low;)g+=j.step;for(;h-j.step>=j.high;)h-=j.step;for(j.min=g,j.max=h,j.range=j.max-j.min,j.values=[],f=j.min;f<=j.max;f+=j.step)j.values.push(c.roundWithPrecision(f));return j},c.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},c.createChartRect=function(a,b,d){var e=!(!b.axisX&&!b.axisY),f=e?b.axisY.offset:0,g=e?b.axisX.offset:0,h=a.width()||c.stripUnit(b.width)||0,i=a.height()||c.stripUnit(b.height)||0,j=c.normalizePadding(b.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===b.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===b.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},c.createGrid=function(a,b,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",c.extend({type:"grid",axis:d,index:b,group:g,element:k},j))},c.createLabel=function(a,b,d,e,f,g,h,i,j,k,l){var m,n={};if(n[f.units.pos]=a+h[f.units.pos],n[f.counterUnits.pos]=h[f.counterUnits.pos],n[f.units.len]=b,n[f.counterUnits.len]=g-10,k){var o=''+e[d]+"";m=i.foreignObject(o,c.extend({style:"overflow: visible;"},n))}else m=i.elem("text",n,j.join(" ")).text(e[d]);l.emit("draw",c.extend({type:"label",axis:f,index:d,group:i,element:m,text:e[d]},n))},c.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},c.optionsProvider=function(b,d,e){function f(b){var f=h;if(h=c.extend({},j),d)for(i=0;i1){var i=[];return h.forEach(function(a){i.push(g(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(i)}if(a=h[0].pathCoordinates,d=h[0].valueData,a.length<=4)return c.Interpolation.none()(a,d);for(var j,k=(new c.Svg.Path).move(a[0],a[1],!1,d[0]),l=0,m=a.length;m-2*!j>l;l+=2){var n=[{x:+a[l-2],y:+a[l-1]},{x:+a[l],y:+a[l+1]},{x:+a[l+2],y:+a[l+3]},{x:+a[l+4],y:+a[l+5]}];j?l?m-4===l?n[3]={x:+a[0],y:+a[1]}:m-2===l&&(n[2]={x:+a[0],y:+a[1]},n[3]={x:+a[2],y:+a[3]}):n[0]={x:+a[m-2],y:+a[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+a[l],y:+a[l+1]}),k.curve(e*(-n[0].x+6*n[1].x+n[2].x)/6+f*n[2].x,e*(-n[0].y+6*n[1].y+n[2].y)/6+f*n[2].y,e*(n[1].x+6*n[2].x-n[3].x)/6+f*n[2].x,e*(n[1].y+6*n[2].y-n[3].y)/6+f*n[2].y,n[2].x,n[2].y,!1,d[(l+2)/2])}return k}},c.Interpolation.step=function(a){var b={postpone:!0};return a=c.extend({},b,a),function(b,d){for(var e=new c.Svg.Path,f=!0,g=2;g1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(h){var k=i.elem("path",{d:h.stringify()},a.classNames.area,!0).attr({values:b.normalized[g]},c.xmlNs.uri);this.eventEmitter.emit("draw",{type:"area",values:b.normalized[g],path:h.clone(),series:f,seriesIndex:g,axisX:d,axisY:e,chartRect:j,index:g,group:i,element:k})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:e.bounds,chartRect:j,axisX:d,axisY:e,svg:this.svg,options:a})}function e(a,b,d,e){c.Line["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Line=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a){var b,d={raw:this.data,normalized:a.distributeSeries?c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y").map(function(a){return[a]}):c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y")};this.svg=c.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var e=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars){var i=c.serialMap(d.normalized,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+b.x||0,y:a.y+b.y||0}},{x:0,y:0})});b=c.getHighLow([i],c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y")}else b=c.getHighLow(d.normalized,c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y");b.high=+a.high||(0===a.high?0:b.high),b.low=+a.low||(0===a.low?0:b.low);var j,k,l,m,n,o=c.createChartRect(this.svg,a,f.padding);k=a.distributeSeries&&a.stackBars?d.raw.labels.slice(0,1):d.raw.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})):a.axisX.type.call(c,c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})),l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y,d,o,{ticks:k}):a.axisY.type.call(c,c.Axis.units.y,d,o,a.axisY)):(l=m=void 0===a.axisX.type?new c.StepAxis(c.Axis.units.x,d,o,{ticks:k}):a.axisX.type.call(c,c.Axis.units.x,d,o,a.axisX),j=n=void 0===a.axisY.type?new c.AutoScaleAxis(c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})):a.axisY.type.call(c,c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),d.raw.series.forEach(function(b,e){var f,h,i=e-(d.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/d.normalized.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/d.normalized[e].length/2,h=g.elem("g"),h.attr({"series-name":b.name,meta:c.serialize(b.meta)},c.xmlNs.uri),h.addClass([a.classNames.series,b.className||a.classNames.series+"-"+c.alphaNumerate(e)].join(" ")),d.normalized[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,d.normalized[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,d.normalized[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,d.normalized[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,d.normalized[e])},l instanceof c.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],v[l.counterUnits.pos+"1"]=a.stackBars?t:p,v[l.counterUnits.pos+"2"]=a.stackBars?q[k]:r[l.counterUnits.pos],v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1),s=h.elem("line",v,a.classNames.bar).attr({value:[g.x,g.y].filter(function(a){return a}).join(","),meta:c.getMetaData(b,k)},c.xmlNs.uri), +this.eventEmitter.emit("draw",c.extend({type:"bar",value:g,index:k,meta:c.getMetaData(b,k),series:b,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function e(a,b,d,e){c.Bar["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,onlyInteger:!1,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,horizontalBars:!1,distributeSeries:!1,reverseData:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Bar=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function e(a){var b,e,f,h,i,j=[],k=a.startAngle,l=c.getDataArray(this.data,a.reverseData);this.svg=c.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=c.createChartRect(this.svg,a,g.padding),f=Math.min(e.width()/2,e.height()/2),i=a.total||l.reduce(function(a,b){return a+b},0),f-=a.donut?a.donutWidth/2:0,h="outside"===a.labelPosition||a.donut?f:"center"===a.labelPosition?0:f/2,h+=a.labelOffset;var m={x:e.x1+e.width()/2,y:e.y2+e.height()/2},n=1===this.data.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;a.showLabel&&(b=this.svg.elem("g",null,null,!0));for(var o=0;o180,0,r.x,r.y);a.donut||t.line(m.x,m.y);var u=j[o].elem("path",{d:t.stringify()},a.donut?a.classNames.sliceDonut:a.classNames.slicePie);if(u.attr({value:l[o],meta:c.serialize(p.meta)},c.xmlNs.uri),a.donut&&u.attr({style:"stroke-width: "+ +a.donutWidth+"px"}),this.eventEmitter.emit("draw",{type:"slice",value:l[o],totalDataSum:i,index:o,meta:p.meta,series:p,group:j[o],element:u,path:t.clone(),center:m,radius:f,startAngle:k,endAngle:q}),a.showLabel){var v=c.polarToCartesian(m.x,m.y,h,k+(q-k)/2),w=a.labelInterpolationFnc(this.data.labels?this.data.labels[o]:l[o],o);if(w||0===w){var x=b.elem("text",{dx:v.x,dy:v.y,"text-anchor":d(m,v,a.labelDirection)},a.classNames.label).text(""+w);this.eventEmitter.emit("draw",{type:"label",index:o,group:b,element:x,text:""+w,x:v.x,y:v.y})}}k=q}this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function f(a,b,d,e){c.Pie["super"].constructor.call(this,a,b,g,c.extend({},g,d),e)}var g={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:c.noop,labelDirection:"neutral",reverseData:!1};c.Pie=c.Base.extend({constructor:f,createChart:e,determineAnchorPosition:d})}(window,document,a),a}); +//# sourceMappingURL=chartist.min.js.map \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/demo.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/demo.js new file mode 100644 index 0000000..b4bb5ee --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/demo.js @@ -0,0 +1,152 @@ +type = ['','info','success','warning','danger']; + + +demo = { + initPickColor: function(){ + $('.pick-class-label').click(function(){ + var new_class = $(this).attr('new-class'); + var old_class = $('#display-buttons').attr('data-class'); + var display_div = $('#display-buttons'); + if(display_div.length) { + var display_buttons = display_div.find('.btn'); + display_buttons.removeClass(old_class); + display_buttons.addClass(new_class); + display_div.attr('data-class', new_class); + } + }); + }, + + initChartist: function(){ + + var dataSales = { + labels: ['9:00AM', '12:00AM', '3:00PM', '6:00PM', '9:00PM', '12:00PM', '3:00AM', '6:00AM'], + series: [ + [287, 385, 490, 492, 554, 586, 698, 695, 752, 788, 846, 944], + [67, 152, 143, 240, 287, 335, 435, 437, 539, 542, 544, 647], + [23, 113, 67, 108, 190, 239, 307, 308, 439, 410, 410, 509] + ] + }; + + var optionsSales = { + lineSmooth: false, + low: 0, + high: 800, + showArea: true, + height: "245px", + axisX: { + showGrid: false, + }, + lineSmooth: Chartist.Interpolation.simple({ + divisor: 3 + }), + showLine: false, + showPoint: false, + }; + + var responsiveSales = [ + ['screen and (max-width: 640px)', { + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Line('#chartHours', dataSales, optionsSales, responsiveSales); + + + var data = { + labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + series: [ + [542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895], + [412, 243, 280, 580, 453, 353, 300, 364, 368, 410, 636, 695] + ] + }; + + var options = { + seriesBarDistance: 10, + axisX: { + showGrid: false + }, + height: "245px" + }; + + var responsiveOptions = [ + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Bar('#chartActivity', data, options, responsiveOptions); + + var dataPreferences = { + series: [ + [25, 30, 20, 25] + ] + }; + + var optionsPreferences = { + donut: true, + donutWidth: 40, + startAngle: 0, + total: 100, + showLabel: false, + axisX: { + showGrid: false + } + }; + + Chartist.Pie('#chartPreferences', dataPreferences, optionsPreferences); + + Chartist.Pie('#chartPreferences', { + labels: ['62%','32%','6%'], + series: [62, 32, 6] + }); + }, + + initGoogleMaps: function(){ + var myLatlng = new google.maps.LatLng(40.748817, -73.985428); + var mapOptions = { + zoom: 13, + center: myLatlng, + scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page + styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}] + + } + var map = new google.maps.Map(document.getElementById("map"), mapOptions); + + var marker = new google.maps.Marker({ + position: myLatlng, + title:"Hello World!" + }); + + // To add the marker to the map, call setMap(); + marker.setMap(map); + }, + + showNotification: function(from, align){ + color = Math.floor((Math.random() * 4) + 1); + + $.notify({ + icon: "pe-7s-gift", + message: "Welcome to Light Bootstrap Dashboard - a beautiful freebie for every web developer." + + },{ + type: type[color], + timer: 4000, + placement: { + from: from, + align: align + } + }); + } + + +} + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/jquery-1.10.2.js b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/jquery-1.10.2.js new file mode 100644 index 0000000..d6f6ac8 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/html/assets/js/jquery-1.10.2.js @@ -0,0 +1,9789 @@ +/*! + * jQuery JavaScript Library v1.10.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:48Z + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<10 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.10.2", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( jQuery.support.ownLast ) { + for ( key in obj ) { + return core_hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.10.2 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
    "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + + var all, a, input, select, fragment, opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
    a"; + + // Finish early in limited (non-browser) environments + all = div.getElementsByTagName("*") || []; + a = div.getElementsByTagName("a")[ 0 ]; + if ( !a || !a.style || !all.length ) { + return support; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName("tbody").length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName("link").length; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + support.opacity = /^0.5/.test( a.style.opacity ); + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!a.style.cssFloat; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; + + // Will be defined later + support.inlineBlockNeedsLayout = false; + support.shrinkWrapBlocks = false; + support.pixelPosition = false; + support.deleteExpando = true; + support.noCloneEvent = true; + support.reliableMarginRight = true; + support.boxSizingReliable = true; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: IE<9 + // Iteration over object's inherited properties before its own. + for ( i in jQuery( support ) ) { + break; + } + support.ownLast = i !== "0"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior. + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
    "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})({}); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "applet": true, + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + data = null, + i = 0, + elem = this[0]; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( name.indexOf("data-") === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // Use proper attribute retrieval(#6932, #12072) + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + jQuery.expr.attrHandle[ name ] = fn; + return ret; + } : + function( elem, name, isXML ) { + return isXML ? + undefined : + elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = + // Some attributes are constructed with empty-string values when not defined + function( elem, name, isXML ) { + var ret; + return isXML ? + undefined : + (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + }; + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ret.specified ? + ret.value : + undefined; + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = ret.push( cur ); + break; + } + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
    ", "
    " ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + col: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
    ", "
    " ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
    " && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(" + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/donutchartssimple.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/README.md b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/dashboard.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/graphs.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/metricdescriptions.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/notifications.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/table.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/template.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartmethod.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartpackage.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartx.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/defaultclassmetrics.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/overview_metric_data.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..e7028e7 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-json", "Number of Highly Problematic Classes":0, "Number of Entities":5, "Number of Problematic Classes":1, "Class Lines of Code":153, "Number of External Packages":15, "Number of Packages":2, "Number of External Entities":163} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/packagedependency.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..f3e9b40 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/packagedependency.js @@ -0,0 +1,8 @@ +var matrix = [[0,0],[1,0]] +var packages = [{ +"name": " org.ugp.serialx.json", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.json.converters", "color": " #6baed6" +} +]; diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/summary_data.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..b72461b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 0,count:0}, +{label:"fair quality attributes", color: "#007F24", value: 153,count:5}]; diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/sunburst_data.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..91b21c2 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,108 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-json", "value":153, +"prmetrics":{"5":1,"6":1,"7":1,"8":1,"9":2,"10":1,"11":2}, +"prmetricvalues":{"5":0,"6":5,"7":1,"8":153,"9":15,"10":2,"11":163}, +"children": [ { +"name": "org.ugp.serialx.json", "value":95, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":1,"13":0,"14":1,"3":1,"1":1,"0":1,"17":0.5,"6":1,"18":0.0,"8":95,"19":0.5,"2":1,"15":1,"16":52}, +"children":[ +{ +"name": "JsonSerializer","key": "n","value":95, +"metrics":{"20":2,"21":1,"22":1,"23":5,"24":2,"25":1,"26":3,"0":4,"27":1,"28":2,"29":5,"30":5,"31":1,"32":4,"33":1,"34":1,"35":1,"36":2,"16":3,"37":1,"4":2,"8":2,"2":2,"3":4,"1":3}, +"metricvalues":{"20":8,"21":1,"38":1,"22":0,"23":1.667,"24":90,"25":0,"26":5,"0":4,"27":15,"28":54,"29":0.993,"30":1.111,"31":3,"32":0.839,"39":0,"33":0,"34":38,"40":1,"35":4,"36":8,"16":52,"37":5,"4":2,"8":95,"2":2,"3":4,"1":3} +} +] +},{ +"name": "org.ugp.serialx.json.converters", "value":58, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":4,"13":0,"14":4,"3":1,"1":1,"0":1,"17":0.0,"6":4,"18":0.0,"8":58,"19":1.0,"2":1,"15":0,"16":25}, +"children":[ +{ +"name": "JsonVariableConverter","key": "k","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":11,"25":0,"26":3,"0":2,"27":1,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":6,"35":0,"36":2,"16":5,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "JsonNumberConverter","key": "p","value":6, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":5,"25":0,"26":2,"0":2,"27":1,"28":3,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":2,"35":0,"36":2,"16":2,"37":0,"4":1,"8":6,"2":1,"3":1,"1":2} +}, +{ +"name": "JsonObjectConverter","key": "l","value":27, +"metrics":{"20":2,"21":1,"22":1,"23":5,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":1,"37":1,"4":1,"8":1,"2":2,"3":1,"1":2}, +"metricvalues":{"20":8,"21":0,"38":1,"22":0,"23":1.5,"24":26,"25":0,"26":3,"0":2,"27":2,"28":14,"29":0.0,"30":0.0,"31":0,"32":0.375,"39":1,"33":1,"34":12,"40":0,"35":0,"36":7,"16":12,"37":1,"4":1,"8":27,"2":2,"3":1,"1":2} +}, +{ +"name": "JsonCharacterConverter","key": "o","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"22":1,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":4,"28":6,"29":0.833,"30":0.0,"31":0,"32":0.55,"33":0,"34":4,"35":0,"36":2,"16":6,"37":0,"4":1,"8":13,"2":1,"3":1,"1":2} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/table_data.js b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..d311b2e --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#0)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT';var EQ_Table5_Title = 'List of all classes (#5)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1JsonSerializer ▄ ▄ ▄ ▄95medium-highlow-mediumhighlow-medium2JsonObjectConverter ▄ ▄ ▄ ▄27low-mediumlow-mediumlowlow3JsonCharacterConv... ▄ ▄ ▄ ▄13low-mediumlowlowlow4JsonVariableConve... ▄ ▄ ▄ ▄12low-mediumlowlowlow5JsonNumberConverter ▄ ▄ ▄ ▄6low-mediumlowlowlow'; \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/report.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/reportforprint.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/sunburst.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-json/codemr/serialx-json/html/main_report/htmlx/treemap.html b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/main_report/index.html b/SerialX-json/codemr/serialx-json/html/main_report/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/main_report/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/html/workingsets.js b/SerialX-json/codemr/serialx-json/html/workingsets.js new file mode 100644 index 0000000..ae48439 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/html/workingsets.js @@ -0,0 +1,3 @@ +var EQ_workingSetList = [ +{name: 'serialx-json', path:'serialx-json'} +]; diff --git a/SerialX-json/codemr/serialx-json/serialx-json.mdl b/SerialX-json/codemr/serialx-json/serialx-json.mdl new file mode 100644 index 0000000000000000000000000000000000000000..78ab49f247e7f8b52fd36477530d91e7ec0ab1d7 GIT binary patch literal 20668 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 literal 0 HcmV?d00001 diff --git a/SerialX-json/codemr/serialx-json/serialx-json.qa b/SerialX-json/codemr/serialx-json/serialx-json.qa new file mode 100644 index 0000000..1e4766b --- /dev/null +++ b/SerialX-json/codemr/serialx-json/serialx-json.qa @@ -0,0 +1 @@ +{"metrics":{"Number of Highly Problematic Classes":0,"Number of Entities":5,"Number of Problematic Classes":1,"Class Lines of Code":153,"Number of External Packages":15,"Number of Packages":2,"Number of External Entities":163},"distributions":{"Coupling":{"distribution":[0,3,2,0,0,0],"locDistribution":[0,31,122,0,0,0]},"Lack of Cohesion":{"distribution":[0,4,0,0,1,0],"locDistribution":[0,58,0,0,95,0]},"Complexity":{"distribution":[0,0,4,1,0,0],"locDistribution":[0,0,58,95,0,0]}}} \ No newline at end of file diff --git a/SerialX-json/codemr/serialx-json/serialx-json.ws b/SerialX-json/codemr/serialx-json/serialx-json.ws new file mode 100644 index 0000000..6f80b02 --- /dev/null +++ b/SerialX-json/codemr/serialx-json/serialx-json.ws @@ -0,0 +1 @@ +{"serialx-json":{"name":"serialx-json","packages":{"org.ugp.serialx.json":{"packageName":"org.ugp.serialx.json","isAll":false,"classes":["Lorg/ugp/serialx/json/JsonSerializer;"]},"org.ugp.serialx.json.converters":{"packageName":"org.ugp.serialx.json.converters","isAll":false,"classes":["Lorg/ugp/serialx/json/converters/JsonVariableConverter;","Lorg/ugp/serialx/json/converters/JsonNumberConverter;","Lorg/ugp/serialx/json/converters/JsonObjectConverter;","Lorg/ugp/serialx/json/converters/JsonCharacterConverter;"]}}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/graphs/all_bymodularity.cmr b/SerialX-juss/codemr/serialx-juss/graphs/all_bymodularity.cmr new file mode 100644 index 0000000..6d30006 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/graphs/all_bymodularity.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":4},{"@type":"int","id":"#edges","v":2},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"q":{"x":486.0,"y":270.0},"v":{"x":222.0,"y":204.0},"k":{"x":50.0,"y":342.0},"m":{"x":477.0,"y":50.0}},"vList":[{"type":"q"},{"type":"m"},{"type":"v"},{"type":"k"}],"eList":[{"L":[{"s":"q","d":"m","k":2,"w":1},{"s":"q","d":"m","k":58,"w":2}]},{"L":[{"s":"v","d":"k","k":53,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/graphs/all_bypackage.cmr b/SerialX-juss/codemr/serialx-juss/graphs/all_bypackage.cmr new file mode 100644 index 0000000..ad9560a --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/graphs/all_bypackage.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":4},{"@type":"int","id":"#edges","v":2},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"q":{"x":581.0,"y":367.0},"v":{"x":626.0,"y":50.0},"k":{"x":50.0,"y":634.0},"m":{"x":595.0,"y":267.0}},"vList":[{"type":"q"},{"type":"m"},{"type":"v"},{"type":"k"}],"eList":[{"L":[{"s":"q","d":"m","k":2,"w":1},{"s":"q","d":"m","k":58,"w":2}]},{"L":[{"s":"v","d":"k","k":53,"w":1}]}],"clusterMap":{"q":1,"v":3,"k":2,"m":1}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/graphs/all_byprojectmodule.cmr b/SerialX-juss/codemr/serialx-juss/graphs/all_byprojectmodule.cmr new file mode 100644 index 0000000..aee73da --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/graphs/all_byprojectmodule.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":4},{"@type":"int","id":"#edges","v":2},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"q":{"x":243.0,"y":124.0},"v":{"x":152.0,"y":173.0},"k":{"x":50.0,"y":188.0},"m":{"x":311.0,"y":50.0}},"vList":[{"type":"q"},{"type":"m"},{"type":"v"},{"type":"k"}],"eList":[{"L":[{"s":"v","d":"k","k":53,"w":1}]},{"L":[{"s":"q","d":"m","k":2,"w":1},{"s":"q","d":"m","k":58,"w":2}]}],"clusterMap":{"q":1,"v":1,"k":1,"m":1}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/graphs/all_nm.cmr b/SerialX-juss/codemr/serialx-juss/graphs/all_nm.cmr new file mode 100644 index 0000000..8a38504 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/graphs/all_nm.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":4},{"@type":"int","id":"#edges","v":2},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"q":{"x":486.0,"y":270.0},"v":{"x":222.0,"y":204.0},"k":{"x":50.0,"y":342.0},"m":{"x":477.0,"y":50.0}},"vList":[{"type":"q"},{"type":"m"},{"type":"v"},{"type":"k"}],"eList":[{"L":[{"s":"q","d":"m","k":2,"w":1},{"s":"q","d":"m","k":58,"w":2}]},{"L":[{"s":"v","d":"k","k":53,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/graphs/all_nm_inheritance.cmr b/SerialX-juss/codemr/serialx-juss/graphs/all_nm_inheritance.cmr new file mode 100644 index 0000000..151286e --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/graphs/all_nm_inheritance.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":2},{"@type":"int","id":"#edges","v":1},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"q":{"x":172.0,"y":50.0},"m":{"x":50.0,"y":50.0}},"vList":[{"type":"q"},{"type":"m"}],"eList":[{"L":[{"s":"q","d":"m","k":2,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.html b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.html new file mode 100644 index 0000000..4eb99c3 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.png b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bymodularity.png new file mode 100644 index 0000000000000000000000000000000000000000..7b806da8a5b3465459faea6ed0afd74ea768d8de GIT binary patch literal 2664 zcmeHJ`&Uw19`~sEDzntdBp){`A0=s-nqYcwYE%m5SoW~6ZiD$q!6!zj+`7xAR@rT7 zK0@%8nH7nd8lnQnYtoFU)Rda}08^tPz(+ue$Q-g?=9iiI1MXUTueJB*wZG?k_B!ia zK7c`4TEHv}3=Ayy?G62_fdTNNewrCV$nKf#S_1)2W=9mn4RFv({vw4+!Pg0CH@Tslp_sY zz;7Yos)+wRe2=xr`tfS6grTNQ_4FwgmG1>GnOm2e*?RG(VeOl`tw++nNJ@FZCaj}%2=U@0>QH{PpRvaM)bOq+gK#C`k@zCpP%eM&ca^Y7-j*htAG#m-GA6_uB#k(qP_sg-=&h1AH&egTB?jI)^-q~q$6(i|cmvvxN|7oj!1oe)K;1XuEk`;n(UCFwtS$Y6N?o0CQ3QCX zp?Cw0!f+L58ZvKDUYR#18DiYT56yS}Cm0h_V?*eBRG{aMTGB9(4~Bpw@xGY|;BZgU z2fe-T#Yf}gzKq-Yl>cIAIcAtjBx*CYZrM*+H@#l#-A%@AcXb7LCSvYW)|v0vA>%-@ z7F(|hnJp30SwE{p)OB5@Tc8tLHXAx|^XkarZlPEH>{K~VWi%=9g$f$(w))yBC3Z$_ z0ODR`WQq#U3odPr_dqq4J5Oz?6Wy4ljYdO=t2n_YQ2cJ*F~Cmckb&2sC##yQ361tn zQ}hAFKiHW{kJ{7*a?5_hLcb!TQK=G{&V8NnnU)`WfP4EpH~@hK!RB~;3S1QJ44|m> z053;`kn;I!ah{@>CC2OA-(Kc1MK^r%Wu}WQ8MwLLt|OL?De)$4$)`ns z3C9ddYea|Xb&moUpG$*cxa{pQAt-7&;5C@jb6;N&Y2>JYHG<{xT=hgEz{0n3G%Wal zGFL9$A|dBaB2l~S>JW)z1+#+S>TjYbfap9rJTjjUfa5(XDD(?~I+leL#1u#K!K4of zJ}%;zRxMRj62j+0+i8GUqM26s*256TvOyU#?^W*CvGlGSs7ko6I8}E#goX*gEkHqQ z>9NZbVtHPEIr?T*0aq87^>k(y;xWtyA9_tA~W*0|e z*FgfD@o=uVUEXzQviM>?58_UXb74_{u}Pr>cn%MbxO$d!Lo@-e0{ls((9nxs~wB(=h5Dfatf_G?a8R+BHI< z>J-Uyh2cu0Wt~M4hKx%8yr7lXrSY+Y?xWXGJn+xEMs^z*;Ka5$51o1D2uDV9@j*KW$qEu|a}Z;-xK8ZNE!d!uay$ z+<_ApYv>5?lGL}u?O z42Tz!AaxVpmXN%-z+X3d;GWdF;DKKOCAPMm#YqvS#szIXRpwF!T^e}{|J0?MFS+y0 zznBvrkH1m#$w`V|FQ}U&Yo;Hp$C~LdSM{LJaBS*)r3-&dtDXmnf zap`;QC2tBLXV0inDm{%)#}z6e?UT>D#O<#l@!jPF9K(~XCjSV!BHa< n7qhh&%>NvJcHsZ(fYyrda^$Q53`K|jAPx3~VM3X^PhR*p83(%0 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.html b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.html new file mode 100644 index 0000000..15b473b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.png b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_bypackage.png new file mode 100644 index 0000000000000000000000000000000000000000..9b96480e387c89a4b4e5d160ff5cd37f330d75c4 GIT binary patch literal 3448 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 azNdH{*6-m;CBc7Gh@-ZSHWgOXfBp}hflRCb literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.html b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.html new file mode 100644 index 0000000..34d6644 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.png b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_byprojectmodule.png new file mode 100644 index 0000000000000000000000000000000000000000..975836f2418b365406aea956876a406cac9f8767 GIT binary patch literal 2323 zcmeHJYgCd480JF@%S&yZE{d0|9b4A2m3c|a%9dG;F7pZknKLxR3u!7!+D%S5Wwoi9 z*H#NT4Yj-yh}0Ac^0GQ=3B*?oQAuPPpyKy2cG{2q+y9-N^StN0=e<1VdEfWXd*vu5 z)PAY+QUn5FA9i5haRdU`{g>GwEs?#`TOkC(W+ZIip73nKq=KBN(7THN(1uM$bcdqb z6gtURY-sDQCxy??m#@c;TBU<0aFo^^$0A)N8BKfG?=L*q;p-BTmQm*)Uf5?l^4Zso z_x%F#J=tvE^+_1ay_7Qqw`A70cl24;J(Fl7d1b>z-nSO=yUaO;(ef7yXSS*k%gG0G zfF~X&Y&`!J;5+cLpF8}Us3;}LJT0-eHP1>Er4xZFheQW}IlK+uMSQ(u%B0y9yhVyt zziu5z<2!j$`hYdktx+~q8yr0)lndTG-X2(1W~y6a9Ym1IMppvfc;n@W>O+!`bt@>O z6@WLn+9<Q^9}mWOtN@RpIV8Ufa1i%HF=XT)zODh zAXb5J`vj3k%QBxfWg3&=QApO+d{6dDdSx9LpV2g8sm8l^Ht}N%91jS^WA8`;s8&hW zLhZgk+NL3w%trHvp@}Xc{|_Qg`^74-`%~QwSGn21ViFhN*BlkHDh=s&`*i>MBZT=q z!!xQ(e<$mpm8~$dRxt107<8P#_+g(gUiX`=6y{RC&RKzR1DHb$w6@`h#rFc32O*H- z-ldB0e`Ou?V7~J8JWe@}2B`qX7hr-H8`Qx$)6cC2Yp8%H0&wp&<+h)jpY1^zyYQQZ z-D|+OPK!8JK1_qiT!dp`0b?|M<64{S&)wSBUMfIm%dfg1H|NN&u0g_fOx(4E<0w8| zS!6s*psPh?gWh<>AW!x#vb%y01h=Wxe(kk^v&XInCk8efK15h3q@USm4+{*qKmj(- z<^Abe5$0x?vo7_lqNzpy-CEFcnNrh>dcR5;i~E?0jbaOCo+zUfTy{c&_%Y9q z_#8IGs~m3VJX3|b{N2LkhyQ`(pHTevDLpZzs|_n7Zbmo;gM-zFB2%JghZ|7RMPM{i ztI;GSu_qNcLh6NKS{q(T6HO0sgB4V6$ZF@}08oH(8>{i<7$qB}mpwa3(zoZ;E>W3; z@#Tg4kH38}>?S^l>zG1nIO?X8y@AYNX;D>y()_^L?8JEWciOE2eJFT8NKdvv( zyvUtXsixC2#iF8;g$NJE79VGvuym#mU2hyXT#c1Av*hVjK{7o9ja9okHT@;P1B64} zIaOyz-V|sUy0<;5yYFr_4)Gq)A6?V$xDK%6Os<9DVvXSCY76Po+x8u1HtXS$ovn7+k{@fz%BY%aC9}+i5e**V zOfujv2PW=@a13S@8}7v|HoEwK_+3Qq;Sm{I>_{y@)XGhXzZmlwX(SStM;I-s?%bHd z-V_~hglXo~vx17*Y&%f1( zrGK~&1<%DyWhy!OKg2dTOsVJ^RK6il?tdw6z|z3gJr<=b>u*VF)oY}=B~K^%QWbgK z>Tvr2hq%=~R3U_G%jmxuvETG+Jf^9RPkBGoImfcx*SUz|ViCJK0JIDzIw`H#)oJFc zC4u6^-abvL#@{@oCpz^m&`d^&DQ?=y0~~3VG|=lAn>5BW{i-0!BjmSMfiGR!E*zKx8Q0%0Inu z*=(_&*9(?kB<%ycif%ZM<>YOs3n;Yj$a;ERv@5hq@=MGh3MxQhzK=tmGb$u4NyYS% zQ?$OIncb~e!I}Z<5R^Q(cYAR{3Dv8aWK?7k=dSK{v~x}CU$iQG^cnkEW!9!`B+OJo vd1<4K&!Yjr>Jw|bNB`sh4g8lj0Nb9jD?b!7!SS&?JBYBaF#8(zp1ANQ;YAS} literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.html b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.html new file mode 100644 index 0000000..4eb99c3 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.png b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm.png new file mode 100644 index 0000000000000000000000000000000000000000..7b806da8a5b3465459faea6ed0afd74ea768d8de GIT binary patch literal 2664 zcmeHJ`&Uw19`~sEDzntdBp){`A0=s-nqYcwYE%m5SoW~6ZiD$q!6!zj+`7xAR@rT7 zK0@%8nH7nd8lnQnYtoFU)Rda}08^tPz(+ue$Q-g?=9iiI1MXUTueJB*wZG?k_B!ia zK7c`4TEHv}3=Ayy?G62_fdTNNewrCV$nKf#S_1)2W=9mn4RFv({vw4+!Pg0CH@Tslp_sY zz;7Yos)+wRe2=xr`tfS6grTNQ_4FwgmG1>GnOm2e*?RG(VeOl`tw++nNJ@FZCaj}%2=U@0>QH{PpRvaM)bOq+gK#C`k@zCpP%eM&ca^Y7-j*htAG#m-GA6_uB#k(qP_sg-=&h1AH&egTB?jI)^-q~q$6(i|cmvvxN|7oj!1oe)K;1XuEk`;n(UCFwtS$Y6N?o0CQ3QCX zp?Cw0!f+L58ZvKDUYR#18DiYT56yS}Cm0h_V?*eBRG{aMTGB9(4~Bpw@xGY|;BZgU z2fe-T#Yf}gzKq-Yl>cIAIcAtjBx*CYZrM*+H@#l#-A%@AcXb7LCSvYW)|v0vA>%-@ z7F(|hnJp30SwE{p)OB5@Tc8tLHXAx|^XkarZlPEH>{K~VWi%=9g$f$(w))yBC3Z$_ z0ODR`WQq#U3odPr_dqq4J5Oz?6Wy4ljYdO=t2n_YQ2cJ*F~Cmckb&2sC##yQ361tn zQ}hAFKiHW{kJ{7*a?5_hLcb!TQK=G{&V8NnnU)`WfP4EpH~@hK!RB~;3S1QJ44|m> z053;`kn;I!ah{@>CC2OA-(Kc1MK^r%Wu}WQ8MwLLt|OL?De)$4$)`ns z3C9ddYea|Xb&moUpG$*cxa{pQAt-7&;5C@jb6;N&Y2>JYHG<{xT=hgEz{0n3G%Wal zGFL9$A|dBaB2l~S>JW)z1+#+S>TjYbfap9rJTjjUfa5(XDD(?~I+leL#1u#K!K4of zJ}%;zRxMRj62j+0+i8GUqM26s*256TvOyU#?^W*CvGlGSs7ko6I8}E#goX*gEkHqQ z>9NZbVtHPEIr?T*0aq87^>k(y;xWtyA9_tA~W*0|e z*FgfD@o=uVUEXzQviM>?58_UXb74_{u}Pr>cn%MbxO$d!Lo@-e0{ls((9nxs~wB(=h5Dfatf_G?a8R+BHI< z>J-Uyh2cu0Wt~M4hKx%8yr7lXrSY+Y?xWXGJn+xEMs^z*;Ka5$51o1D2uDV9@j*KW$qEu|a}Z;-xK8ZNE!d!uay$ z+<_ApYv>5?lGL}u?O z42Tz!AaxVpmXN%-z+X3d;GWdF;DKKOCAPMm#YqvS#szIXRpwF!T^e}{|J0?MFS+y0 zznBvrkH1m#$w`V|FQ}U&Yo;Hp$C~LdSM{LJaBS*)r3-&dtDXmnf zap`;QC2tBLXV0inDm{%)#}z6e?UT>D#O<#l@!jPF9K(~XCjSV!BHa< n7qhh&%>NvJcHsZ(fYyrda^$Q53`K|jAPx3~VM3X^PhR*p83(%0 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.html b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.html new file mode 100644 index 0000000..7a63188 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.png b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/all_nm_inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..70b9503b49b8723437f83a2d146d4b7765037293 GIT binary patch literal 1402 zcmeAS@N?(olHy`uVBq!ia0y~yU~~Xs4kn<8()EG_;*iDl{k=S z?;yXx-i2jiN+PQpck7CM&fLu{DvL}C4{<58M{VJ3YcXqd^j^54R>10<<+(FybAnd+ zrmW~ti0I~6)WIidxOW|&#o<3QUO$SQ``vEO_h;KH=I5F>tjRqr-@wP{JflI;=YW7( z0*A0c3#Y^(7M?_=HUlK#*?JFJyXVWs-m1;`^5M*ni^9+O-?Mj1ddbJn4_R_lgIR1=em`)iS%2QX&-;s?yjdr|E>_~)+Sw;}$I098D{H*& zW_`>)bH>{2u7-ZScX86^pX@QIfB&&q|4z-X(@*pN+1LF(yY|gp`}*?G@$cvI`cH484_n?aTE_9?)mQI)op-ZpzTfM4{@~Cz|NZs( z7F*8w)qQ`rI{jbnkEh1p_wW4iRCS PQyDy6{an^LB{Ts5{+I3& literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/graph_htmls/graphlist.js b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/graphlist.js new file mode 100644 index 0000000..d9164f0 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/graph_htmls/graphlist.js @@ -0,0 +1 @@ +var EQ_graphHTMLText = ''; \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/Xdonut.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/Xdonut.html new file mode 100644 index 0000000..ab4d736 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/Xdonut.html @@ -0,0 +1,107 @@ + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/circlepack.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/circlepack.html new file mode 100644 index 0000000..1c6adf1 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/circlepack.html @@ -0,0 +1,113 @@ + + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + +
    +
    + + + + + +
    +
    +
    +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/dependency.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/dependency.html new file mode 100644 index 0000000..05b4312 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/dependency.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donut.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donut.html new file mode 100644 index 0000000..8ac1af3 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donut.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutcharts.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutcharts.html new file mode 100644 index 0000000..cc9471b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutcharts.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutchartssimple.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/README.md b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/dashboard.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/graphs.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/metricdescriptions.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/notifications.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/table.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/template.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartmethod.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartpackage.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartx.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/defaultclassmetrics.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/overview_metric_data.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..aeebadf --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-juss working set: {serialx-juss}", "Number of Highly Problematic Classes":0, "Number of Entities":10, "Number of Problematic Classes":1, "Class Lines of Code":820, "Number of External Packages":11, "Number of Packages":3, "Number of External Entities":48} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/packagedependency.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..6cb3f91 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/packagedependency.js @@ -0,0 +1,11 @@ +var matrix = [[0,0,0],[0,0,0],[0,1,0]] +var packages = [{ +"name": " org.ugp.serialx.juss.protocols", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.juss", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.juss.converters", "color": " #9ecae1" +} +]; diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/summary_data.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..af74881 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 336,count:1}, +{label:"fair quality attributes", color: "#007F24", value: 484,count:9}]; diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/sunburst_data.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..20ae9de --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,139 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-juss working set: {serialx-juss}", "value":820, +"prmetrics":{"5":1,"6":1,"7":1,"8":1,"9":2,"10":1,"11":1}, +"prmetricvalues":{"5":0,"6":10,"7":1,"8":820,"9":11,"10":3,"11":48}, +"children": [ { +"name": "org.ugp.serialx.juss.protocols", "value":113, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":2,"13":1,"14":3,"3":1,"1":1,"0":1,"17":0.25,"6":4,"18":0.25,"8":113,"19":1.0,"2":1,"15":0,"16":44}, +"children":[ +{ +"name": "UniversalObjectInstantiationProtocol","key": "m","value":40, +"metrics":{"20":1,"21":1,"22":1,"23":3,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.4,"24":38,"25":1,"26":2,"0":2,"27":5,"28":14,"29":0.9,"30":0.0,"31":0,"32":0.55,"39":0,"33":0,"34":9,"40":1,"35":0,"36":3,"16":14,"37":1,"4":1,"8":40,"2":1,"3":1,"1":2} +}, +{ +"name": "SelfSerializableProtocol","key": "q","value":9, +"metrics":{"20":1,"21":1,"22":1,"23":5,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":1,"38":1,"22":0,"23":2.0,"24":8,"25":0,"26":3,"0":2,"27":3,"28":4,"29":0.0,"30":0.0,"31":0,"32":0.444,"39":1,"33":0,"34":1,"40":0,"35":0,"36":0,"16":3,"37":2,"4":1,"8":9,"2":1,"3":1,"1":2} +}, +{ +"name": "SelfSerializable","key": "t","value":2, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":1,"25":0,"26":1,"0":1,"27":1,"28":1,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":0,"35":0,"36":0,"16":1,"37":0,"4":1,"8":2,"2":1,"3":1,"1":1} +}, +{ +"name": "AutoProtocol","key": "s","value":62, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":4,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"22":4,"23":0.0,"24":52,"25":0,"26":2,"0":2,"27":11,"28":26,"29":0.836,"30":0.878,"31":3,"32":0.662,"33":0,"34":19,"35":0,"36":3,"16":26,"37":0,"4":2,"8":62,"2":1,"3":2,"1":2} +} +] +},{ +"name": "org.ugp.serialx.juss", "value":336, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":2,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":1,"3":1,"1":1,"0":1,"17":0.5,"6":1,"18":0.0,"8":336,"19":0.5,"2":1,"15":1,"16":175}, +"children":[ +{ +"name": "JussSerializer","key": "k","value":336, +"metrics":{"20":2,"21":1,"22":1,"23":4,"24":3,"25":1,"26":3,"0":5,"27":2,"28":2,"29":5,"30":5,"31":1,"32":4,"33":1,"34":2,"35":1,"36":2,"16":5,"37":1,"4":3,"8":3,"2":2,"3":4,"1":5}, +"metricvalues":{"20":9,"21":1,"38":1,"22":2,"23":0.444,"24":322,"25":0,"26":4,"0":5,"27":27,"28":86,"29":0.991,"30":1.071,"31":2,"32":0.852,"39":0,"33":0,"34":68,"40":1,"35":2,"36":9,"16":175,"37":3,"4":3,"8":336,"2":2,"3":4,"1":5} +} +] +},{ +"name": "org.ugp.serialx.juss.converters", "value":371, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":5,"13":0,"14":5,"3":1,"1":2,"0":2,"17":0.0,"6":5,"18":0.0,"8":371,"19":1.0,"2":1,"15":0,"16":204}, +"children":[ +{ +"name": "VariableConverter","key": "u","value":105, +"metrics":{"20":1,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":5,"21":0,"22":1,"23":0.25,"24":101,"25":0,"26":2,"0":3,"27":8,"28":35,"29":0.978,"30":1.0,"31":1,"32":0.662,"33":0,"34":28,"35":2,"36":5,"16":61,"37":1,"4":2,"8":105,"2":1,"3":2,"1":3} +}, +{ +"name": "OperationGroups","key": "r","value":82, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"22":1,"23":0.0,"24":80,"25":0,"26":1,"0":2,"27":1,"28":20,"29":1.0,"30":0.0,"31":0,"32":0.464,"33":0,"34":19,"35":3,"36":3,"16":49,"37":0,"4":2,"8":82,"2":1,"3":1,"1":2} +}, +{ +"name": "ObjectConverter","key": "v","value":76, +"metrics":{"20":2,"21":1,"22":1,"23":3,"24":2,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":2,"37":1,"4":2,"8":2,"2":2,"3":1,"1":2}, +"metricvalues":{"20":10,"21":0,"38":1,"22":0,"23":0.4,"24":75,"25":0,"26":2,"0":2,"27":5,"28":34,"29":0.0,"30":0.0,"31":0,"32":0.433,"39":1,"33":1,"34":31,"40":0,"35":0,"36":9,"16":36,"37":1,"4":2,"8":76,"2":2,"3":1,"1":2} +}, +{ +"name": "ArrayConverter","key": "o","value":77, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":76,"25":0,"26":1,"0":2,"27":4,"28":23,"29":0.0,"30":0.0,"31":0,"32":0.417,"33":0,"34":20,"35":0,"36":3,"16":44,"37":0,"4":2,"8":77,"2":1,"3":1,"1":2} +}, +{ +"name": "ImportConverter","key": "p","value":31, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":1,"37":1,"4":1,"8":1,"2":2,"3":1,"1":1}, +"metricvalues":{"20":6,"21":0,"22":0,"23":0.0,"24":30,"25":0,"26":1,"0":2,"27":3,"28":17,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":0,"34":15,"35":0,"36":6,"16":14,"37":0,"4":1,"8":31,"2":2,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/table_data.js b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..38284ea --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#1)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1JussSerializer ▄ ▄ ▄ ▄336175862724';var EQ_Table5_Title = 'List of all classes (#10)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1JussSerializer ▄ ▄ ▄ ▄336very-highlow-mediumhighmedium-high2ObjectConverter ▄ ▄ ▄ ▄76low-mediumlow-mediumlowlow-medium3ImportConverter ▄ ▄ ▄ ▄31lowlow-mediumlowlow4VariableConverter ▄ ▄ ▄ ▄105medium-highlowlow-mediumlow-medium5OperationGroups ▄ ▄ ▄ ▄82low-mediumlowlowlow-medium6ArrayConverter ▄ ▄ ▄ ▄77low-mediumlowlowlow-medium7AutoProtocol ▄ ▄ ▄ ▄62low-mediumlowlow-mediumlow-medium8UniversalObjectIn... ▄ ▄ ▄ ▄40low-mediumlowlowlow9SelfSerializableP... ▄ ▄ ▄ ▄9low-mediumlowlowlow10SelfSerializable ▄ ▄ ▄ ▄2lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/report.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/reportforprint.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/sunburst.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/treemap.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/index.html b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/html_report_serialx-juss/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/animate.min.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/animate.min.css new file mode 100644 index 0000000..0b6a47d --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/animate.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license - http://opensource.org/licenses/MIT + +Copyright (c) 2015 Daniel Eden +*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}@keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}100%{opacity:1}}@keyframes fadeIn{from{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}100%{opacity:0}}@keyframes fadeOut{from{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/bootstrap.min.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/bootstrap.min.css new file mode 100644 index 0000000..d65c66b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;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:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;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,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/demo.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/demo.css new file mode 100644 index 0000000..febe628 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/demo.css @@ -0,0 +1,61 @@ +@media (min-width: 992px){ + .typo-line{ + padding-left: 140px; + margin-bottom: 40px; + position: relative; + } + + .typo-line .category{ + transform: translateY(-50%); + top: 50%; + left: 0px; + position: absolute; + } +} + +.all-icons [class*="pe-"]{ + font-size: 40px; +} +.all-icons input{ + border: 0; +} +.all-icons .font-icon-detail{ + text-align: center; + padding: 45px 0px 30px; + border: 1px solid #e5e5e5; + border-radius: 6px; + margin: 15px 0; +} +.all-icons .font-icon-detail input{ + margin: 25px auto 0; + width: 100%; + text-align: center; + display: block; + color: #aaa; + font-size: 13px; +} + +#map{ + position:relative; + width:100%; + height: calc(100% - 60px); +} + +.places-buttons .btn{ + margin-bottom: 30px +} +.sidebar .nav > li.active-pro{ + position: absolute; + width: 100%; + bottom: 10px; +} +.sidebar .nav > li.active-pro a{ + background: rgba(255, 255, 255, 0.14); + opacity: 1; + color: #FFFFFF; +} + +.table-upgrade td:nth-child(2), +.table-upgrade td:nth-child(3){ + text-align: center; +} diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/font-awesome.min.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/helptip.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/helptip.css new file mode 100644 index 0000000..8cca39a --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/helptip.css @@ -0,0 +1,148 @@ + +/*------------------------- + Inline help tip +--------------------------*/ + +.help-tip{ + position: relative; + top: 4px; + left: 0px; + text-align: center; + border-radius: 10%; + width: 48px; + height: 24px; + font-size: 14px; + line-height: 26px; + cursor: default; +} + + +.help-tip:before{ + content: url(../img/help.png); + font-weight: bold; + color:#fff; +} + +.help-tip:hover div{ + display:block; + transform-origin: 100% 0%; + + -webkit-animation: fadeIn 0.3s ease-in-out; + animation: fadeIn 0.3s ease-in-out; + +} + +.help-tip div{ + display: none; + text-align: left; + background-color: white; + padding: 20px; + width: 300px; + position: absolute; + border-radius: 3px; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + left: -100px; + color: black; + font-size: 13px; + line-height: 1.4; +} + +/* arrow */ +.help-tip div:before{ + position: absolute; + content: ''; + width:0; + height: 0; + border:6px solid transparent; + border-bottom-color: white; + left:100px; + top:-12px; + +} + +.help-tip div:after{ + width:100%; + height:40px; + content:''; + position: absolute; + top:-40px; + left:0; +} + + +@-webkit-keyframes fadeIn { + 0% { + opacity:0; + transform: scale(0.6); + } + + 100% { + opacity:100%; + transform: scale(1); + } +} + +@keyframes fadeIn { + 0% { opacity:0; } + 100% { opacity:100%; } +} + + + +@media (max-width: 1024px) { + #bsaHolder, footer{ display:none;} +} + + .tip-legend .legend-title { + text-align: left; + margin-bottom: 5px; + font-weight: bold; + font-size: 90%; + } + .tip-legend ul { + margin: 0; + margin-bottom: 5px; + padding: 0; + float: left; + list-style: none; + } + .tip-legend ul li { + font-size: 80%; + list-style: lower-roman; + margin-left:25px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li { + + font-size: 80%; + list-style: none; + margin-left: 0px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li span { + + float: left; + height: 16px; + width: 30px; + margin-right: 5px; + margin-left:0px; + border: 1px solid #999; + } + .tip-legend .tip-metric-source { + font-size: 90%; + color: #999; + clear: both; + } + .tip-legend a { + color: #777; + } + + .tip-subsection { + text-align: left; + margin-bottom: 5px; + font-size: 90%; + } \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/light-bootstrap-dashboard.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/light-bootstrap-dashboard.css new file mode 100644 index 0000000..3ce28f5 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/light-bootstrap-dashboard.css @@ -0,0 +1,3393 @@ +/* light colors */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } +} +@-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(360deg); + } +} +@-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + } +} +/* Font Smoothing */ +body, +h1, .h1, +h2, .h2, +h3, .h3, +h4, .h4, +h5, .h5, +h6, .h6, +p, +.navbar, +.brand, +.btn-simple, +.alert, +a, +.td-name, +td, +button.close { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-family: "Roboto","Helvetica Neue",Arial,sans-serif; + font-weight: 400; +} + +h1, .h1, h2, .h2, h3, .h3, h4, .h4 { + font-weight: 300; + margin: 30px 0 15px; +} + +h1, .h1 { + font-size: 52px; +} + +h2, .h2 { + font-size: 36px; +} + +h3, .h3 { + font-size: 28px; + margin: 20px 0 10px; +} + +h4, .h4 { + font-size: 22px; + line-height: 30px; +} + +h5, .h5 { + font-size: 16px; + margin-bottom: 15px; +} + +h6, .h6 { + font-size: 14px; + font-weight: 600; + text-transform: uppercase; +} + +p { + font-size: 16px; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #9A9A9A; + font-weight: 300; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 60%; +} + +h1 .subtitle { + display: block; + margin: 0 0 30px; +} + +.text-muted { + color: #9A9A9A; +} + +.text-primary, .text-primary:hover { + color: #1D62F0 !important; +} + +.text-info, .text-info:hover { + color: #1DC7EA !important; +} + +.text-success, .text-success:hover { + color: #87CB16 !important; +} + +.text-warning, .text-warning:hover { + color: #FF9500 !important; +} + +.text-danger, .text-danger:hover { + color: #FF4A55 !important; +} + +/* General overwrite */ +body, +.wrapper { + min-height: 100vh; + position: relative; +} + +a { + color: #1DC7EA; +} +a:hover, a:focus { + color: #42d0ed; + text-decoration: none; +} + +a:focus, a:active, +button::-moz-focus-inner, +input::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +select::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + outline: 0; +} + +.ui-slider-handle:focus, +.navbar-toggle, +input:focus { + outline: 0 !important; +} + +/* Animations */ +.form-control, +.input-group-addon, +.tagsinput, +.navbar, +.navbar .alert { + -webkit-transition: all 300ms linear; + -moz-transition: all 300ms linear; + -o-transition: all 300ms linear; + -ms-transition: all 300ms linear; + transition: all 300ms linear; +} + +.sidebar .nav a, +.table > tbody > tr .td-actions .btn { + -webkit-transition: all 150ms ease-in; + -moz-transition: all 150ms ease-in; + -o-transition: all 150ms ease-in; + -ms-transition: all 150ms ease-in; + transition: all 150ms ease-in; +} + +.btn { + -webkit-transition: all 100ms ease-in; + -moz-transition: all 100ms ease-in; + -o-transition: all 100ms ease-in; + -ms-transition: all 100ms ease-in; + transition: all 100ms ease-in; +} + +.fa { + width: 18px; + text-align: center; +} + +.margin-top { + margin-top: 50px; +} + +.wrapper { + position: relative; + top: 0; + height: 100vh; +} + +.sidebar { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 260px; + display: block; + z-index: 1; + color: #fff; + font-weight: 200; + background-size: cover; + background-position: center center; +} +.sidebar .sidebar-wrapper { + position: relative; + max-height: none; + min-height: 100%; + overflow: hidden; + width: 260px; + z-index: 4; +} +.sidebar .sidebar-background { + position: absolute; + z-index: 1; + height: 100%; + width: 100%; + display: block; + top: 0; + left: 0; + background-size: cover; + background-position: center center; +} +.sidebar .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar .nav { + margin-top: 20px; +} +.sidebar .nav li > a { + color: #FFFFFF; + margin: 5px 15px; + opacity: .86; + border-radius: 4px; +} +.sidebar .nav li:hover > a { + background: rgba(255, 255, 255, 0.13); + opacity: 1; +} +.sidebar .nav li.active > a { + color: #FFFFFF; + opacity: 1; + background: rgba(255, 255, 255, 0.23); +} +.sidebar .nav p { + margin: 0; + line-height: 30px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.sidebar .nav i { + font-size: 28px; + float: left; + margin-right: 15px; + line-height: 30px; + width: 30px; + text-align: center; +} + +.sidebar .logo, +body > .navbar-collapse .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p, +body > .navbar-collapse .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text, +body > .navbar-collapse .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim, +body > .navbar-collapse .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img, +body > .navbar-collapse .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar:after, .sidebar:before, +body > .navbar-collapse:after, +body > .navbar-collapse:before { + display: block; + content: ""; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +.sidebar:before, +body > .navbar-collapse:before { + opacity: .33; + background: #000000; +} +.sidebar:after, +body > .navbar-collapse:after { + background: #787878; + background: -moz-linear-gradient(top, #787878 0%, #343434 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #787878), color-stop(100%, #343434)); + background: -webkit-linear-gradient(top, #787878 0%, #343434 100%); + background: -o-linear-gradient(top, #787878 0%, #343434 100%); + background: -ms-linear-gradient(top, #787878 0%, #343434 100%); + background: linear-gradient(to bottom, #787878 0%, #343434 100%); + background-size: 150% 150%; + z-index: 3; + opacity: 1; +} +.sidebar[data-image]:after, .sidebar.has-image:after, +body > .navbar-collapse[data-image]:after, +body > .navbar-collapse.has-image:after { + opacity: .77; +} +.sidebar[data-color="blue"]:after, +body > .navbar-collapse[data-color="blue"]:after { + background: #1F77D0; + background: -moz-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1F77D0), color-stop(100%, #533ce1)); + background: -webkit-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -o-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -ms-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: linear-gradient(to bottom, #1F77D0 0%, #533ce1 100%); + background-size: 150% 150%; +} +.sidebar[data-color="azure"]:after, +body > .navbar-collapse[data-color="azure"]:after { + background: #1DC7EA; + background: -moz-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1DC7EA), color-stop(100%, #4091ff)); + background: -webkit-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -o-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -ms-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: linear-gradient(to bottom, #1DC7EA 0%, #4091ff 100%); + background-size: 150% 150%; +} +.sidebar[data-color="green"]:after, +body > .navbar-collapse[data-color="green"]:after { + background: #87CB16; + background: -moz-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #87CB16), color-stop(100%, #6dc030)); + background: -webkit-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -o-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -ms-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: linear-gradient(to bottom, #87CB16 0%, #6dc030 100%); + background-size: 150% 150%; +} +.sidebar[data-color="orange"]:after, +body > .navbar-collapse[data-color="orange"]:after { + background: #FFA534; + background: -moz-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FFA534), color-stop(100%, #ff5221)); + background: -webkit-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -o-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -ms-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: linear-gradient(to bottom, #FFA534 0%, #ff5221 100%); + background-size: 150% 150%; +} +.sidebar[data-color="red"]:after, +body > .navbar-collapse[data-color="red"]:after { + background: #FB404B; + background: -moz-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FB404B), color-stop(100%, #bb0502)); + background: -webkit-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -o-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -ms-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: linear-gradient(to bottom, #FB404B 0%, #bb0502 100%); + background-size: 150% 150%; +} +.sidebar[data-color="purple"]:after, +body > .navbar-collapse[data-color="purple"]:after { + background: #9368E9; + background: -moz-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9368E9), color-stop(100%, #943bea)); + background: -webkit-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -o-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -ms-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: linear-gradient(to bottom, #9368E9 0%, #943bea 100%); + background-size: 150% 150%; +} + +.main-panel { + background: rgba(203, 203, 210, 0.15); + position: relative; + z-index: 2; + float: right; + width: calc(100% - 260px); + min-height: 100%; +} +.main-panel > .content { + padding: 30px 15px; + min-height: calc(100% - 123px); +} +.main-panel > .footer { + border-top: 1px solid #e7e7e7; +} +.main-panel .navbar { + margin-bottom: 0; +} + +.sidebar, +.main-panel { + overflow: auto; + max-height: 100%; + height: 100%; + -webkit-transition-property: top,bottom; + transition-property: top,bottom; + -webkit-transition-duration: .2s,.2s; + transition-duration: .2s,.2s; + -webkit-transition-timing-function: linear,linear; + transition-timing-function: linear,linear; + -webkit-overflow-scrolling: touch; +} + +.btn { + border-width: 2px; + background-color: transparent; + font-weight: 400; + opacity: 0.8; + filter: alpha(opacity=80); + padding: 8px 16px; + border-color: #888888; + color: #888888; +} +.btn:hover, .btn:focus, .btn:active, .btn.active, .open > .btn.dropdown-toggle { + background-color: transparent; + color: #777777; + border-color: #777777; +} +.btn.disabled, .btn.disabled:hover, .btn.disabled:focus, .btn.disabled.focus, .btn.disabled:active, .btn.disabled.active, .btn:disabled, .btn:disabled:hover, .btn:disabled:focus, .btn:disabled.focus, .btn:disabled:active, .btn:disabled.active, .btn[disabled], .btn[disabled]:hover, .btn[disabled]:focus, .btn[disabled].focus, .btn[disabled]:active, .btn[disabled].active, fieldset[disabled] .btn, fieldset[disabled] .btn:hover, fieldset[disabled] .btn:focus, fieldset[disabled] .btn.focus, fieldset[disabled] .btn:active, fieldset[disabled] .btn.active { + background-color: transparent; + border-color: #888888; +} +.btn.btn-fill { + color: #FFFFFF; + background-color: #888888; + opacity: 1; + filter: alpha(opacity=100); +} +.btn.btn-fill:hover, .btn.btn-fill:focus, .btn.btn-fill:active, .btn.btn-fill.active, .open > .btn.btn-fill.dropdown-toggle { + background-color: #777777; + color: #FFFFFF; +} +.btn.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn .caret { + border-top-color: #888888; +} +.btn:hover, .btn:focus { + opacity: 1; + filter: alpha(opacity=100); + outline: 0 !important; +} +.btn:active, .btn.active, .open > .btn.dropdown-toggle { + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; +} +.btn.btn-icon { + padding: 8px; +} + +.btn-primary { + border-color: #3472F7; + color: #3472F7; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { + background-color: transparent; + color: #1D62F0; + border-color: #1D62F0; +} +.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary:disabled, .btn-primary:disabled:hover, .btn-primary:disabled:focus, .btn-primary:disabled.focus, .btn-primary:disabled:active, .btn-primary:disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active { + background-color: transparent; + border-color: #3472F7; +} +.btn-primary.btn-fill { + color: #FFFFFF; + background-color: #3472F7; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary.btn-fill:hover, .btn-primary.btn-fill:focus, .btn-primary.btn-fill:active, .btn-primary.btn-fill.active, .open > .btn-primary.btn-fill.dropdown-toggle { + background-color: #1D62F0; + color: #FFFFFF; +} +.btn-primary.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-primary .caret { + border-top-color: #3472F7; +} + +.btn-success { + border-color: #87CB16; + color: #87CB16; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { + background-color: transparent; + color: #049F0C; + border-color: #049F0C; +} +.btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success:disabled, .btn-success:disabled:hover, .btn-success:disabled:focus, .btn-success:disabled.focus, .btn-success:disabled:active, .btn-success:disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled].active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active { + background-color: transparent; + border-color: #87CB16; +} +.btn-success.btn-fill { + color: #FFFFFF; + background-color: #87CB16; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-success.btn-fill:hover, .btn-success.btn-fill:focus, .btn-success.btn-fill:active, .btn-success.btn-fill.active, .open > .btn-success.btn-fill.dropdown-toggle { + background-color: #049F0C; + color: #FFFFFF; +} +.btn-success.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-success .caret { + border-top-color: #87CB16; +} + +.btn-info { + border-color: #1DC7EA; + color: #1DC7EA; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { + background-color: transparent; + color: #42d0ed; + border-color: #42d0ed; +} +.btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info:disabled, .btn-info:disabled:hover, .btn-info:disabled:focus, .btn-info:disabled.focus, .btn-info:disabled:active, .btn-info:disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled].active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active { + background-color: transparent; + border-color: #1DC7EA; +} +.btn-info.btn-fill { + color: #FFFFFF; + background-color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-info.btn-fill:hover, .btn-info.btn-fill:focus, .btn-info.btn-fill:active, .btn-info.btn-fill.active, .open > .btn-info.btn-fill.dropdown-toggle { + background-color: #42d0ed; + color: #FFFFFF; +} +.btn-info.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-info .caret { + border-top-color: #1DC7EA; +} + +.btn-warning { + border-color: #FF9500; + color: #FF9500; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + background-color: transparent; + color: #ED8D00; + border-color: #ED8D00; +} +.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning:disabled, .btn-warning:disabled:hover, .btn-warning:disabled:focus, .btn-warning:disabled.focus, .btn-warning:disabled:active, .btn-warning:disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active { + background-color: transparent; + border-color: #FF9500; +} +.btn-warning.btn-fill { + color: #FFFFFF; + background-color: #FF9500; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-warning.btn-fill:hover, .btn-warning.btn-fill:focus, .btn-warning.btn-fill:active, .btn-warning.btn-fill.active, .open > .btn-warning.btn-fill.dropdown-toggle { + background-color: #ED8D00; + color: #FFFFFF; +} +.btn-warning.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-warning .caret { + border-top-color: #FF9500; +} + +.btn-danger { + border-color: #FF4A55; + color: #FF4A55; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { + background-color: transparent; + color: #EE2D20; + border-color: #EE2D20; +} +.btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger:disabled, .btn-danger:disabled:hover, .btn-danger:disabled:focus, .btn-danger:disabled.focus, .btn-danger:disabled:active, .btn-danger:disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active { + background-color: transparent; + border-color: #FF4A55; +} +.btn-danger.btn-fill { + color: #FFFFFF; + background-color: #FF4A55; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-danger.btn-fill:hover, .btn-danger.btn-fill:focus, .btn-danger.btn-fill:active, .btn-danger.btn-fill.active, .open > .btn-danger.btn-fill.dropdown-toggle { + background-color: #EE2D20; + color: #FFFFFF; +} +.btn-danger.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-danger .caret { + border-top-color: #FF4A55; +} + +.btn-neutral { + border-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral:hover, .btn-neutral:focus, .btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: transparent; + color: #FFFFFF; + border-color: #FFFFFF; +} +.btn-neutral.disabled, .btn-neutral.disabled:hover, .btn-neutral.disabled:focus, .btn-neutral.disabled.focus, .btn-neutral.disabled:active, .btn-neutral.disabled.active, .btn-neutral:disabled, .btn-neutral:disabled:hover, .btn-neutral:disabled:focus, .btn-neutral:disabled.focus, .btn-neutral:disabled:active, .btn-neutral:disabled.active, .btn-neutral[disabled], .btn-neutral[disabled]:hover, .btn-neutral[disabled]:focus, .btn-neutral[disabled].focus, .btn-neutral[disabled]:active, .btn-neutral[disabled].active, fieldset[disabled] .btn-neutral, fieldset[disabled] .btn-neutral:hover, fieldset[disabled] .btn-neutral:focus, fieldset[disabled] .btn-neutral.focus, fieldset[disabled] .btn-neutral:active, fieldset[disabled] .btn-neutral.active { + background-color: transparent; + border-color: #FFFFFF; +} +.btn-neutral.btn-fill { + color: #FFFFFF; + background-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus, .btn-neutral.btn-fill:active, .btn-neutral.btn-fill.active, .open > .btn-neutral.btn-fill.dropdown-toggle { + background-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-neutral .caret { + border-top-color: #FFFFFF; +} +.btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: #FFFFFF; + color: #888888; +} +.btn-neutral.btn-fill, .btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus { + color: #888888; +} +.btn-neutral.btn-simple:active, .btn-neutral.btn-simple.active { + background-color: transparent; +} + +.btn:disabled, .btn[disabled], .btn.disabled { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.btn-round { + border-width: 1px; + border-radius: 30px !important; + padding: 9px 18px; +} +.btn-round.btn-icon { + padding: 9px; +} + +.btn-simple { + border: 0; + font-size: 16px; + padding: 8px 16px; +} +.btn-simple.btn-icon { + padding: 8px; +} + +.btn-lg { + font-size: 18px; + border-radius: 6px; + padding: 14px 30px; + font-weight: 400; +} +.btn-lg.btn-round { + padding: 15px 30px; +} +.btn-lg.btn-simple { + padding: 16px 30px; +} + +.btn-sm { + font-size: 12px; + border-radius: 3px; + padding: 5px 10px; +} +.btn-sm.btn-round { + padding: 6px 10px; +} +.btn-sm.btn-simple { + padding: 7px 10px; +} + +.btn-xs { + font-size: 12px; + border-radius: 3px; + padding: 1px 5px; +} +.btn-xs.btn-round { + padding: 2px 5px; +} +.btn-xs.btn-simple { + padding: 3px 5px; +} + +.btn-wd { + min-width: 140px; +} + +.btn-group.select { + width: 100%; +} + +.btn-group.select .btn { + text-align: left; +} + +.btn-group.select .caret { + position: absolute; + top: 50%; + margin-top: -1px; + right: 8px; +} + +.form-control::-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control::-webkit-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-ms-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; + color: #565656; + padding: 8px 12px; + height: 40px; + -webkit-box-shadow: none; + box-shadow: none; +} +.form-control:focus { + background-color: #FFFFFF; + border: 1px solid #AAAAAA; + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; + color: #333333; +} +.has-success .form-control, .has-error .form-control, .has-success .form-control:focus, .has-error .form-control:focus { + border-color: #E3E3E3; + -webkit-box-shadow: none; + box-shadow: none; +} +.has-success .form-control { + color: #87CB16; +} +.has-success .form-control:focus { + border-color: #87CB16; +} +.has-error .form-control { + color: #FF4A55; +} +.has-error .form-control:focus { + border-color: #FF4A55; +} +.form-control + .form-control-feedback { + border-radius: 6px; + font-size: 14px; + margin-top: -7px; + position: absolute; + right: 10px; + top: 50%; + vertical-align: middle; +} +.open .form-control { + border-radius: 4px 4px 0 0; + border-bottom-color: transparent; +} + +.input-lg { + height: 55px; + padding: 14px 30px; +} + +.has-error .form-control-feedback { + color: #FF4A55; +} + +.has-success .form-control-feedback { + color: #87CB16; +} + +.input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; +} +.has-success .input-group-addon, .has-error .input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; +} +.has-error .form-control:focus + .input-group-addon { + border-color: #FF4A55; + color: #FF4A55; +} +.has-success .form-control:focus + .input-group-addon { + border-color: #87CB16; + color: #87CB16; +} +.form-control:focus + .input-group-addon, .form-control:focus ~ .input-group-addon { + background-color: #FFFFFF; + border-color: #9A9A9A; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-right: 0 none; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-left: 0 none; +} + +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + background-color: #F5F5F5; + color: #888888; + cursor: not-allowed; +} + +.input-group-btn .btn { + border-width: 1px; + padding: 9px 16px; +} + +.input-group-btn .btn-default:not(.btn-fill) { + border-color: #DDDDDD; +} + +.input-group-btn:last-child > .btn { + margin-left: 0; +} + +.input-group-focus .input-group-addon { + border-color: #9A9A9A; +} + +.alert { + border: 0; + border-radius: 0; + color: #FFFFFF; + padding: 10px 15px; + font-size: 14px; +} +.container .alert { + border-radius: 4px; +} +.navbar .alert { + border-radius: 0; + left: 0; + position: absolute; + right: 0; + top: 85px; + width: 100%; + z-index: 3; +} +.navbar:not(.navbar-transparent) .alert { + top: 70px; +} +.alert span[data-notify="icon"] { + font-size: 30px; + display: block; + left: 15px; + position: absolute; + top: 50%; + margin-top: -15px; +} +.alert button.close { + position: absolute; + right: 10px; + top: 50%; + margin-top: -13px; + z-index: 1033; + background-color: #FFFFFF; + display: block; + border-radius: 50%; + opacity: .4; + line-height: 11px; + width: 25px; + height: 25px; + outline: 0 !important; + text-align: center; + padding: 3px; + font-weight: 300; +} +.alert button.close:hover { + opacity: .55; +} +.alert .close ~ span { + display: block; + max-width: 89%; +} +.alert[data-notify="container"] { + padding: 10px 10px 10px 20px; + border-radius: 4px; +} +.alert.alert-with-icon { + padding-left: 65px; +} + +.alert-info { + background-color: #63d8f1; +} + +.alert-success { + background-color: #a1e82c; +} + +.alert-warning { + background-color: #ffbc67; +} + +.alert-danger { + background-color: #fc727a; +} + +.table .radio, +.table .checkbox { + position: relative; + height: 20px; + display: block; + width: 20px; + padding: 0px 0px; + margin: 0px 5px; + text-align: center; +} +.table .radio .icons, +.table .checkbox .icons { + left: 5px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 12px 8px; + vertical-align: middle; +} +.table > thead > tr > th { + border-bottom-width: 1px; + font-size: 12px; + text-transform: uppercase; + color: #9A9A9A; + font-weight: 400; + padding-bottom: 5px; +} +.table .td-actions .btn { + opacity: 0.36; + filter: alpha(opacity=36); +} +.table .td-actions .btn.btn-xs { + padding-left: 3px; + padding-right: 3px; +} +.table .td-actions { + min-width: 90px; +} +.table > tbody > tr { + position: relative; +} +.table > tbody > tr:hover .td-actions .btn { + opacity: 1; + filter: alpha(opacity=100); +} + +/* Checkbox and radio */ +.checkbox, +.radio { + margin-bottom: 12px; + padding-left: 32px; + position: relative; + -webkit-transition: color 0.25s linear; + transition: color 0.25s linear; + font-size: 14px; + font-weight: normal; + line-height: 1.5; + color: #333333; +} + +.checkbox input, +.radio input { + outline: none !important; + display: none; +} + +.checkbox .icons, +.radio .icons { + color: #DDDDDD; + display: block; + height: 20px; + left: 0; + position: absolute; + top: 0; + width: 20px; + text-align: center; + line-height: 21px; + font-size: 20px; + cursor: pointer; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox .icons .first-icon, +.radio .icons .first-icon, +.checkbox .icons .second-icon, +.radio .icons .second-icon { + display: inline-table; + position: absolute; + left: 0; + top: 0; + background-color: transparent; + margin: 0; + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox .icons .second-icon, +.radio .icons .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover, +.radio:hover { + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox:hover .first-icon, +.radio:hover .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover .second-icon, +.radio:hover .second-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.checked, +.radio.checked { + color: #1DC7EA; +} + +.checkbox.checked .first-icon, +.radio.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.checked .second-icon, +.radio.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #1DC7EA; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox.disabled, +.radio.disabled { + cursor: default; + color: #DDDDDD !important; +} + +.checkbox.disabled .icons, +.radio.disabled .icons { + color: #DDDDDD !important; +} + +.checkbox.disabled .first-icon, +.radio.disabled .first-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.disabled .second-icon, +.radio.disabled .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .icons, +.radio.disabled.checked .icons { + color: #DDDDDD; +} + +.checkbox.disabled.checked .first-icon, +.radio.disabled.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .second-icon, +.radio.disabled.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #D9D9D9; +} + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ +.has-switch { + border-radius: 30px; + cursor: pointer; + display: inline-block; + line-height: 1.72222; + overflow: hidden; + position: relative; + text-align: left; + width: 60px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + /* this code is for fixing safari bug with hidden overflow for border-radius */ + -webkit-mask: url("../img/mask.png") 0 0 no-repeat; + -webkit-mask-size: 60px 24px; + mask: url("../img/mask.png") 0 0 no-repeat; +} + +.has-switch.deactivate { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} + +.has-switch.deactivate label, +.has-switch.deactivate span { + cursor: default !important; +} + +.has-switch > div { + position: relative; + top: 0; + width: 100px; +} + +.has-switch > div.switch-animate { + -webkit-transition: left 0.25s ease-out; + transition: left 0.25s ease-out; +} + +.has-switch > div.switch-off { + left: -35px; +} + +.has-switch > div.switch-on { + left: 0; +} + +.has-switch > div label { + background-color: #FFFFFF; + background: white; + background: -moz-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #f1f1f2)); + background: -webkit-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -o-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -ms-linear-gradient(top, white 0%, #f1f1f2 100%); + background: linear-gradient(to bottom, white 0%, #f1f1f2 100%); + background-size: 150% 150%; + box-shadow: 0 1px 1px #FFFFFF inset, 0 1px 1px rgba(0, 0, 0, 0.25); + cursor: pointer; +} + +.has-switch input[type=checkbox] { + display: none; +} + +.has-switch span { + /* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) inset; */ + cursor: pointer; + float: left; + font-size: 11px; + font-weight: 400; + height: 24px; + line-height: 15px; + margin: 0; + padding-bottom: 6px; + padding-top: 5px; + position: relative; + text-align: center; + text-indent: -10px; + width: 50%; + z-index: 1; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch span.switch-left { + background-color: #1DC7EA; + border-left: 1px solid transparent; + border-radius: 30px 0 0 30px; + color: #FFFFFF; +} + +.has-switch .switch-off span.switch-left { + background-color: #DDDDDD; +} + +.has-switch span.switch-right { + border-radius: 0 30px 30px 0; + background-color: #1DC7EA; + color: #ffffff; + text-indent: 1px; +} + +.has-switch .switch-off span.switch-right { + background-color: #DDDDDD; +} + +.has-switch label { + border-radius: 12px; + float: left; + height: 22px; + margin: 1px -13px; + padding: 0; + position: relative; + transition: all 0.25s ease-out 0s; + vertical-align: middle; + width: 22px; + z-index: 100; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch .switch-on .fa-check:before { + margin-left: 10px; +} + +.has-switch:hover .switch-on label { + margin: 1px -17px; + width: 26px; +} + +.has-switch:hover .switch-off label { + margin: 1px -13px; + width: 26px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: transparent; +} + +.navbar { + border: 0; + font-size: 16px; + border-radius: 0; +} +.navbar .navbar-brand { + font-weight: 400; + margin: 5px 0px; + padding: 15px 15px; + font-size: 20px; +} +.navbar .navbar-nav > li > a { + padding: 10px 15px; + margin: 10px 3px; + position: relative; +} +.navbar .navbar-nav > li > a.btn { + margin: 15px 3px; + padding: 8px 16px; +} +.navbar .navbar-nav > li > a.btn-round { + margin: 16px 3px; +} +.navbar .navbar-nav > li > a [class^="fa"] { + font-size: 19px; + position: relative; + line-height: 16px; + top: 1px; +} +.navbar .navbar-nav .notification { + position: absolute; + background-color: #FB404B; + text-align: center; + border-radius: 10px; + min-width: 18px; + padding: 0 5px; + height: 18px; + font-size: 12px; + color: #FFFFFF; + font-weight: bold; + line-height: 18px; + top: 0px; + left: 7px; +} +.navbar .btn { + margin: 15px 3px; + font-size: 14px; +} +.navbar .btn-simple { + font-size: 16px; +} +.navbar.fixed { + width: calc(100% - $sidebar-width); + right: 0; + left: auto; + border-radius: 0; +} + +.navbar-nav > li > .dropdown-menu { + border-radius: 10px; + margin-top: -5px; +} + +.navbar-transparent .navbar-brand, [class*="navbar-ct"] .navbar-brand { + color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .navbar-brand:focus, .navbar-transparent .navbar-brand:hover, [class*="navbar-ct"] .navbar-brand:focus, [class*="navbar-ct"] .navbar-brand:hover { + background-color: transparent; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav > li > a:not(.btn), [class*="navbar-ct"] .navbar-nav > li > a:not(.btn) { + color: #FFFFFF; + border-color: #FFFFFF; + opacity: 0.8; + filter: alpha(opacity=80); +} +.navbar-transparent .navbar-nav > .active > a:not(.btn), +.navbar-transparent .navbar-nav > .active > a:hover:not(.btn), +.navbar-transparent .navbar-nav > .active > a:focus:not(.btn), +.navbar-transparent .navbar-nav > li > a:hover:not(.btn), +.navbar-transparent .navbar-nav > li > a:focus:not(.btn), [class*="navbar-ct"] .navbar-nav > .active > a:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:focus:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:focus:not(.btn) { + background-color: transparent; + border-radius: 3px; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav .nav > li > a.btn:hover, [class*="navbar-ct"] .navbar-nav .nav > li > a.btn:hover { + background-color: transparent; +} +.navbar-transparent .navbar-nav > .dropdown > a .caret, +.navbar-transparent .navbar-nav > .dropdown > a:hover .caret, +.navbar-transparent .navbar-nav > .dropdown > a:focus .caret, [class*="navbar-ct"] .navbar-nav > .dropdown > a .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:hover .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} +.navbar-transparent .navbar-nav > .open > a, +.navbar-transparent .navbar-nav > .open > a:hover, +.navbar-transparent .navbar-nav > .open > a:focus, [class*="navbar-ct"] .navbar-nav > .open > a, +[class*="navbar-ct"] .navbar-nav > .open > a:hover, +[class*="navbar-ct"] .navbar-nav > .open > a:focus { + background-color: transparent; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .btn-default, [class*="navbar-ct"] .btn-default { + color: #FFFFFF; + border-color: #FFFFFF; +} +.navbar-transparent .btn-default.btn-fill, [class*="navbar-ct"] .btn-default.btn-fill { + color: #9A9A9A; + background-color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .btn-default.btn-fill:hover, +.navbar-transparent .btn-default.btn-fill:focus, +.navbar-transparent .btn-default.btn-fill:active, +.navbar-transparent .btn-default.btn-fill.active, +.navbar-transparent .open .dropdown-toggle.btn-fill.btn-default, [class*="navbar-ct"] .btn-default.btn-fill:hover, +[class*="navbar-ct"] .btn-default.btn-fill:focus, +[class*="navbar-ct"] .btn-default.btn-fill:active, +[class*="navbar-ct"] .btn-default.btn-fill.active, +[class*="navbar-ct"] .open .dropdown-toggle.btn-fill.btn-default { + border-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} + +.navbar-transparent .dropdown-menu .divider { + background-color: rgba(255, 255, 255, 0.2); +} + +.nav-open .nav .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} + +.navbar-default { + background-color: rgba(255, 255, 255, 0.96); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); +} +.navbar-default .navbar-nav > li > a:not(.btn) { + color: #9A9A9A; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:not(.btn):hover, +.navbar-default .navbar-nav > .active > a:not(.btn):focus, +.navbar-default .navbar-nav > li > a:not(.btn):hover, +.navbar-default .navbar-nav > li > a:not(.btn):focus { + background-color: transparent; + border-radius: 3px; + color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #1DC7EA; + border-top-color: #1DC7EA; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #1DC7EA; +} +.navbar-default .navbar-nav .navbar-toggle:hover, .navbar-default .navbar-nav .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default:not(.navbar-transparent) .btn-default:hover { + color: #1DC7EA; + border-color: #1DC7EA; +} +.navbar-default:not(.navbar-transparent) .btn-neutral, .navbar-default:not(.navbar-transparent) .btn-neutral:hover, .navbar-default:not(.navbar-transparent) .btn-neutral:active { + color: #9A9A9A; +} + +/* Navbar with icons */ +.navbar-icons.navbar .navbar-brand { + margin-top: 12px; + margin-bottom: 12px; +} +.navbar-icons .navbar-nav > li > a { + text-align: center; + padding: 6px 15px; + margin: 6px 3px; +} +.navbar-icons .navbar-nav [class^="pe"] { + font-size: 30px; + position: relative; +} +.navbar-icons .navbar-nav p { + margin: 3px 0 0; +} + +.navbar-form { + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form .form-control { + border-radius: 0; + border: 0; + padding: 0; + background-color: transparent; + height: 22px; + font-size: 16px; + line-height: 1.5; + color: #E3E3E3; +} +.navbar-transparent .navbar-form .form-control, [class*="navbar-ct"] .navbar-form .form-control { + color: #FFFFFF; + border: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.6); +} + +.navbar-ct-blue { + background-color: #4091e2; +} + +.navbar-ct-azure { + background-color: #63d8f1; +} + +.navbar-ct-green { + background-color: #a1e82c; +} + +.navbar-ct-orange { + background-color: #ffbc67; +} + +.navbar-ct-red { + background-color: #fc727a; +} + +.navbar-transparent { + padding-top: 15px; + background-color: transparent; + border-bottom: 1px solid transparent; +} + +.navbar-toggle { + margin-top: 19px; + margin-bottom: 19px; + border: 0; +} +.navbar-toggle .icon-bar { + background-color: #FFFFFF; +} +.navbar-toggle .navbar-collapse, +.navbar-toggle .navbar-form { + border-color: transparent; +} +.navbar-toggle.navbar-default .navbar-toggle:hover, .navbar-toggle.navbar-default .navbar-toggle:focus { + background-color: transparent; +} + +.footer { + background-color: #FFFFFF; + line-height: 20px; +} +.footer nav > ul { + list-style: none; + margin: 0; + padding: 0; + font-weight: normal; +} +.footer nav > ul a:not(.btn) { + color: #9A9A9A; + display: block; + margin-bottom: 3px; +} +.footer nav > ul a:not(.btn):hover, .footer nav > ul a:not(.btn):focus { + color: #777777; +} +.footer .social-area { + padding: 15px 0; +} +.footer .social-area h5 { + padding-bottom: 15px; +} +.footer .social-area > a:not(.btn) { + color: #9A9A9A; + display: inline-block; + vertical-align: top; + padding: 10px 5px; + font-size: 20px; + font-weight: normal; + line-height: 20px; + text-align: center; +} +.footer .social-area > a:not(.btn):hover, .footer .social-area > a:not(.btn):focus { + color: #777777; +} +.footer .copyright { + color: #777777; + padding: 10px 15px; + margin: 10px 3px; + line-height: 20px; + font-size: 14px; +} +.footer hr { + border-color: #DDDDDD; +} +.footer .title { + color: #777777; +} + +.footer-default { + background-color: #F5F5F5; +} + +.footer:not(.footer-big) nav > ul { + font-size: 14px; +} +.footer:not(.footer-big) nav > ul li { + margin-left: 20px; + float: left; +} +.footer:not(.footer-big) nav > ul a { + padding: 10px 0px; + margin: 10px 10px 10px 0px; +} + +.dropdown-menu { + visibility: hidden; + margin: 0; + padding: 0; + border-radius: 10px; + display: block; + z-index: 9000; + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); +} +.open .dropdown-menu { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; +} +.select .dropdown-menu { + border-radius: 0 0 10px 10px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transform-origin: 50% -40px; + -moz-transform-origin: 50% -40px; + -o-transform-origin: 50% -40px; + -ms-transform-origin: 50% -40px; + transform-origin: 50% -40px; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transition: all 150ms linear; + -moz-transition: all 150ms linear; + -o-transition: all 150ms linear; + -ms-transition: all 150ms linear; + transition: all 150ms linear; + margin-top: -20px; +} +.select.open .dropdown-menu { + margin-top: -1px; +} +.dropdown-menu > li > a { + padding: 8px 16px; + color: #333333; +} +.dropdown-menu > li > a img { + margin-top: -3px; +} +.dropdown-menu > li > a:focus { + outline: 0 !important; +} +.btn-group.select .dropdown-menu { + min-width: 100%; +} +.dropdown-menu > li:first-child > a { + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} +.dropdown-menu > li:last-child > a { + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} +.select .dropdown-menu > li:first-child > a { + border-radius: 0; + border-bottom: 0 none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #F5F5F5; + color: #333333; + opacity: 1; + text-decoration: none; +} +.dropdown-menu.dropdown-blue > li > a:hover, .dropdown-menu.dropdown-blue > li > a:focus { + background-color: rgba(52, 114, 247, 0.2); +} +.dropdown-menu.dropdown-azure > li > a:hover, .dropdown-menu.dropdown-azure > li > a:focus { + background-color: rgba(29, 199, 234, 0.2); +} +.dropdown-menu.ct-green > li > a:hover, .dropdown-menu.ct-green > li > a:focus { + background-color: rgba(135, 203, 22, 0.2); +} +.dropdown-menu.dropdown-orange > li > a:hover, .dropdown-menu.dropdown-orange > li > a:focus { + background-color: rgba(255, 149, 0, 0.2); +} +.dropdown-menu.dropdown-red > li > a:hover, .dropdown-menu.dropdown-red > li > a:focus { + background-color: rgba(255, 74, 85, 0.2); +} + +.dropdown-with-icons > li > a { + padding-left: 0px; + line-height: 28px; +} +.dropdown-with-icons i { + text-align: center; + line-height: 28px; + float: left; +} +.dropdown-with-icons i[class^="pe-"] { + font-size: 24px; + width: 46px; +} +.dropdown-with-icons i[class^="fa"] { + font-size: 14px; + width: 38px; +} + +.btn-group.select { + overflow: hidden; +} + +.btn-group.select.open { + overflow: visible; +} + +.card { + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(63, 63, 68, 0.1); + background-color: #FFFFFF; + margin-bottom: 30px; +} +.card .image { + width: 100%; + overflow: hidden; + height: 260px; + border-radius: 4px 4px 0 0; + position: relative; + -webkit-transform-style: preserve-3d; + -moz-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.card .image img { + width: 100%; +} +.card .filter { + position: absolute; + z-index: 2; + background-color: rgba(0, 0, 0, 0.68); + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + filter: alpha(opacity=0); +} +.card .filter .btn { + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} +.card:hover .filter { + opacity: 1; + filter: alpha(opacity=100); +} +.card .btn-hover { + opacity: 0; + filter: alpha(opacity=0); +} +.card:hover .btn-hover { + opacity: 1; + filter: alpha(opacity=100); +} +.card .content { + padding: 15px 15px 10px 15px; +} +.card .header { + padding: 15px 15px 0; +} +.card .category, +.card label { + font-size: 14px; + font-weight: 400; + color: #9A9A9A; + margin-bottom: 0px; +} +.card .category i, +.card label i { + font-size: 16px; +} +.card label { + font-size: 12px; + margin-bottom: 5px; + text-transform: uppercase; +} +.card .title { + margin: 0; + color: #333333; + font-weight: 300; +} +.card .avatar { + width: 30px; + height: 30px; + overflow: hidden; + border-radius: 50%; + margin-right: 5px; +} +.card .description { + font-size: 14px; + color: #333; +} +.card .footer { + padding: 0; + background-color: transparent; + line-height: 30px; +} +.card .footer .legend { + padding: 5px 0; +} +.card .footer hr { + margin-top: 5px; + margin-bottom: 5px; +} +.card .stats { + color: #a9a9a9; +} +.card .footer div { + display: inline-block; +} +.card .author { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.card .author i { + font-size: 14px; +} +.card h6 { + font-size: 12px; + margin: 0; +} +.card.card-separator:after { + height: 100%; + right: -15px; + top: 0; + width: 1px; + background-color: #DDDDDD; + content: ""; + position: absolute; +} +.card .ct-chart { + margin: 30px 0 30px; + height: 245px; +} +.card .table tbody td:first-child, +.card .table thead th:first-child { + padding-left: 15px; +} +.card .table tbody td:last-child, +.card .table thead th:last-child { + padding-right: 15px; +} +.card .alert { + border-radius: 4px; + position: relative; +} +.card .alert.alert-with-icon { + padding-left: 65px; +} + +.card-user .image { + height: 110px; +} +.card-user .image-plain { + height: 0; + margin-top: 110px; +} +.card-user .author { + text-align: center; + text-transform: none; + margin-top: -70px; +} +.card-user .avatar { + width: 124px; + height: 124px; + border: 5px solid #FFFFFF; + position: relative; + margin-bottom: 15px; +} +.card-user .avatar.border-gray { + border-color: #EEEEEE; +} +.card-user .title { + line-height: 24px; +} +.card-user .content { + min-height: 240px; +} + +.card-user .footer, +.card-price .footer { + padding: 5px 15px 10px; +} +.card-user hr, +.card-price hr { + margin: 5px 15px; +} + +.card-plain { + background-color: transparent; + box-shadow: none; + border-radius: 0; +} +.card-plain .image { + border-radius: 4px; +} + +.ct-label { + fill: rgba(0, 0, 0, 0.4); + color: rgba(0, 0, 0, 0.4); + font-size: 1.3rem; + line-height: 1; +} + +.ct-chart-line .ct-label, +.ct-chart-bar .ct-label { + display: block; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-vertical.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-label.ct-vertical.ct-end { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: end; +} + +.ct-grid { + stroke: rgba(0, 0, 0, 0.2); + stroke-width: 1px; + stroke-dasharray: 2px; +} + +.ct-point { + stroke-width: 8px; + stroke-linecap: round; +} + +.ct-line { + fill: none; + stroke-width: 3px; +} + +.ct-area { + stroke: none; + fill-opacity: 0.8; +} + +.ct-bar { + fill: none; + stroke-width: 10px; +} + +.ct-slice-donut { + fill: none; + stroke-width: 60px; +} + +.ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut { + stroke: #1DC7EA; +} +.ct-series-a .ct-slice-pie, .ct-series-a .ct-area { + fill: #1DC7EA; +} + +.ct-series-b .ct-point, .ct-series-b .ct-line, .ct-series-b .ct-bar, .ct-series-b .ct-slice-donut { + stroke: #FB404B; +} +.ct-series-b .ct-slice-pie, .ct-series-b .ct-area { + fill: #FB404B; +} + +.ct-series-c .ct-point, .ct-series-c .ct-line, .ct-series-c .ct-bar, .ct-series-c .ct-slice-donut { + stroke: #FFA534; +} +.ct-series-c .ct-slice-pie, .ct-series-c .ct-area { + fill: #FFA534; +} + +.ct-series-d .ct-point, .ct-series-d .ct-line, .ct-series-d .ct-bar, .ct-series-d .ct-slice-donut { + stroke: #9368E9; +} +.ct-series-d .ct-slice-pie, .ct-series-d .ct-area { + fill: #9368E9; +} + +.ct-series-e .ct-point, .ct-series-e .ct-line, .ct-series-e .ct-bar, .ct-series-e .ct-slice-donut { + stroke: #87CB16; +} +.ct-series-e .ct-slice-pie, .ct-series-e .ct-area { + fill: #87CB16; +} + +.ct-series-f .ct-point, .ct-series-f .ct-line, .ct-series-f .ct-bar, .ct-series-f .ct-slice-donut { + stroke: #1F77D0; +} +.ct-series-f .ct-slice-pie, .ct-series-f .ct-area { + fill: #1F77D0; +} + +.ct-series-g .ct-point, .ct-series-g .ct-line, .ct-series-g .ct-bar, .ct-series-g .ct-slice-donut { + stroke: #5e5e5e; +} +.ct-series-g .ct-slice-pie, .ct-series-g .ct-area { + fill: #5e5e5e; +} + +.ct-series-h .ct-point, .ct-series-h .ct-line, .ct-series-h .ct-bar, .ct-series-h .ct-slice-donut { + stroke: #dd4b39; +} +.ct-series-h .ct-slice-pie, .ct-series-h .ct-area { + fill: #dd4b39; +} + +.ct-series-i .ct-point, .ct-series-i .ct-line, .ct-series-i .ct-bar, .ct-series-i .ct-slice-donut { + stroke: #35465c; +} +.ct-series-i .ct-slice-pie, .ct-series-i .ct-area { + fill: #35465c; +} + +.ct-series-j .ct-point, .ct-series-j .ct-line, .ct-series-j .ct-bar, .ct-series-j .ct-slice-donut { + stroke: #e52d27; +} +.ct-series-j .ct-slice-pie, .ct-series-j .ct-area { + fill: #e52d27; +} + +.ct-series-k .ct-point, .ct-series-k .ct-line, .ct-series-k .ct-bar, .ct-series-k .ct-slice-donut { + stroke: #55acee; +} +.ct-series-k .ct-slice-pie, .ct-series-k .ct-area { + fill: #55acee; +} + +.ct-series-l .ct-point, .ct-series-l .ct-line, .ct-series-l .ct-bar, .ct-series-l .ct-slice-donut { + stroke: #cc2127; +} +.ct-series-l .ct-slice-pie, .ct-series-l .ct-area { + fill: #cc2127; +} + +.ct-series-m .ct-point, .ct-series-m .ct-line, .ct-series-m .ct-bar, .ct-series-m .ct-slice-donut { + stroke: #1769ff; +} +.ct-series-m .ct-slice-pie, .ct-series-m .ct-area { + fill: #1769ff; +} + +.ct-series-n .ct-point, .ct-series-n .ct-line, .ct-series-n .ct-bar, .ct-series-n .ct-slice-donut { + stroke: #6188e2; +} +.ct-series-n .ct-slice-pie, .ct-series-n .ct-area { + fill: #6188e2; +} + +.ct-series-o .ct-point, .ct-series-o .ct-line, .ct-series-o .ct-bar, .ct-series-o .ct-slice-donut { + stroke: #a748ca; +} +.ct-series-o .ct-slice-pie, .ct-series-o .ct-area { + fill: #a748ca; +} + +.ct-square { + display: block; + position: relative; + width: 100%; +} +.ct-square:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 100%; +} +.ct-square:after { + content: ""; + display: table; + clear: both; +} +.ct-square > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-second { + display: block; + position: relative; + width: 100%; +} +.ct-minor-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 93.75%; +} +.ct-minor-second:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-second { + display: block; + position: relative; + width: 100%; +} +.ct-major-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 88.88889%; +} +.ct-major-second:after { + content: ""; + display: table; + clear: both; +} +.ct-major-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-third { + display: block; + position: relative; + width: 100%; +} +.ct-minor-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 83.33333%; +} +.ct-minor-third:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-third { + display: block; + position: relative; + width: 100%; +} +.ct-major-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 80%; +} +.ct-major-third:after { + content: ""; + display: table; + clear: both; +} +.ct-major-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fourth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fourth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 75%; +} +.ct-perfect-fourth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fourth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fifth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fifth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 66.66667%; +} +.ct-perfect-fifth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fifth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-minor-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 62.5%; +} +.ct-minor-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-golden-section { + display: block; + position: relative; + width: 100%; +} +.ct-golden-section:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 61.8047%; +} +.ct-golden-section:after { + content: ""; + display: table; + clear: both; +} +.ct-golden-section > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-major-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 60%; +} +.ct-major-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-minor-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 56.25%; +} +.ct-minor-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 53.33333%; +} +.ct-major-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-octave { + display: block; + position: relative; + width: 100%; +} +.ct-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 50%; +} +.ct-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-tenth { + display: block; + position: relative; + width: 100%; +} +.ct-major-tenth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 40%; +} +.ct-major-tenth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-tenth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-eleventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-eleventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 37.5%; +} +.ct-major-eleventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-eleventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-twelfth { + display: block; + position: relative; + width: 100%; +} +.ct-major-twelfth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 33.33333%; +} +.ct-major-twelfth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-twelfth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-double-octave { + display: block; + position: relative; + width: 100%; +} +.ct-double-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 25%; +} +.ct-double-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-double-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +@media (min-width: 992px) { + .navbar-form { + margin-top: 21px; + margin-bottom: 21px; + padding-left: 5px; + padding-right: 5px; + } + + .navbar-nav > li > .dropdown-menu, .dropdown .dropdown-menu { + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -moz-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -o-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -ms-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + } + + .navbar-nav > li.open > .dropdown-menu, .dropdown.open .dropdown-menu { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transform-origin: 29px -50px; + -moz-transform-origin: 29px -50px; + -o-transform-origin: 29px -50px; + -ms-transform-origin: 29px -50px; + transform-origin: 29px -50px; + } + + .navbar-nav > li > .dropdown-menu:before { + border-bottom: 11px solid rgba(0, 0, 0, 0.2); + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -11px; + } + + .navbar-nav > li > .dropdown-menu:after { + border-bottom: 11px solid #FFFFFF; + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -10px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:before { + left: auto; + right: 12px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:after { + left: auto; + right: 12px; + } + + .footer:not(.footer-big) nav > ul li:first-child { + margin-left: 0; + } + + body > .navbar-collapse.collapse { + display: none !important; + } + + .card form [class*="col-"] { + padding: 6px; + } + .card form [class*="col-"]:first-child { + padding-left: 15px; + } + .card form [class*="col-"]:last-child { + padding-right: 15px; + } +} +/* Changes for small display */ +@media (max-width: 991px) { + .sidebar { + display: none; + } + + .main-panel { + width: 100%; + } + + .navbar-transparent { + padding-top: 15px; + background-color: rgba(0, 0, 0, 0.45); + } + + body { + position: relative; + } + + .wrapper { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + left: 0; + background-color: white; + } + + .navbar .container { + left: 0; + width: 100%; + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + position: relative; + } + + .navbar .navbar-collapse.collapse, + .navbar .navbar-collapse.collapse.in, + .navbar .navbar-collapse.collapsing { + display: none !important; + } + + .navbar-nav > li { + float: none; + position: relative; + display: block; + } + + body > .navbar-collapse { + position: fixed; + display: block; + top: 0; + height: 100%; + width: 250px; + right: 0; + z-index: 1032; + visibility: visible; + background-color: #999; + overflow-y: visible; + border-top: none; + text-align: left; + padding: 0; + -webkit-transform: translate3d(250px, 0, 0); + -moz-transform: translate3d(250px, 0, 0); + -o-transform: translate3d(250px, 0, 0); + -ms-transform: translate3d(250px, 0, 0); + transform: translate3d(250px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + } + body > .navbar-collapse > ul { + position: relative; + z-index: 4; + overflow-y: scroll; + height: calc(100vh - 61px); + width: 100%; + } + body > .navbar-collapse .nav > li > a { + padding: 30px 25px; + } + body > .navbar-collapse::before { + top: 0; + left: 0; + height: 100%; + width: 100%; + position: absolute; + background-color: #282828; + display: block; + content: ""; + z-index: 1; + } + body > .navbar-collapse .logo { + position: relative; + z-index: 4; + } + + .nav-open .navbar-collapse { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + } + + .nav-open .navbar .container { + left: -250px; + } + + .nav-open .wrapper { + left: 0; + -webkit-transform: translate3d(-250px, 0, 0); + -moz-transform: translate3d(-250px, 0, 0); + -o-transform: translate3d(-250px, 0, 0); + -ms-transform: translate3d(-250px, 0, 0); + transform: translate3d(-250px, 0, 0); + } + + .navbar-toggle .icon-bar { + display: block; + position: relative; + background: #fff; + width: 24px; + height: 2px; + border-radius: 1px; + margin: 0 auto; + } + + .navbar-header .navbar-toggle { + margin: 10px 15px 10px 0; + width: 40px; + height: 40px; + } + + .bar1, + .bar2, + .bar3 { + outline: 1px solid transparent; + } + + .bar1 { + top: 0px; + -webkit-animation: topbar-back 500ms linear 0s; + -moz-animation: topbar-back 500ms linear 0s; + animation: topbar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .bar2 { + opacity: 1; + } + + .bar3 { + bottom: 0px; + -webkit-animation: bottombar-back 500ms linear 0s; + -moz-animation: bottombar-back 500ms linear 0s; + animation: bottombar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar1 { + top: 6px; + -webkit-animation: topbar-x 500ms linear 0s; + -moz-animation: topbar-x 500ms linear 0s; + animation: topbar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar2 { + opacity: 0; + } + + .toggled .bar3 { + bottom: 6px; + -webkit-animation: bottombar-x 500ms linear 0s; + -moz-animation: bottombar-x 500ms linear 0s; + animation: bottombar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + @keyframes topbar-x { + 0% { + top: 0px; + transform: rotate(0deg); + } + 45% { + top: 6px; + transform: rotate(145deg); + } + 75% { + transform: rotate(130deg); + } + 100% { + transform: rotate(135deg); + } + } + @-webkit-keyframes topbar-x { + 0% { + top: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + top: 6px; + -webkit-transform: rotate(145deg); + } + 75% { + -webkit-transform: rotate(130deg); + } + 100% { + -webkit-transform: rotate(135deg); + } + } + @-moz-keyframes topbar-x { + 0% { + top: 0px; + -moz-transform: rotate(0deg); + } + 45% { + top: 6px; + -moz-transform: rotate(145deg); + } + 75% { + -moz-transform: rotate(130deg); + } + 100% { + -moz-transform: rotate(135deg); + } + } + @keyframes topbar-back { + 0% { + top: 6px; + transform: rotate(135deg); + } + 45% { + transform: rotate(-10deg); + } + 75% { + transform: rotate(5deg); + } + 100% { + top: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes topbar-back { + 0% { + top: 6px; + -webkit-transform: rotate(135deg); + } + 45% { + -webkit-transform: rotate(-10deg); + } + 75% { + -webkit-transform: rotate(5deg); + } + 100% { + top: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes topbar-back { + 0% { + top: 6px; + -moz-transform: rotate(135deg); + } + 45% { + -moz-transform: rotate(-10deg); + } + 75% { + -moz-transform: rotate(5deg); + } + 100% { + top: 0px; + -moz-transform: rotate(0); + } + } + @keyframes bottombar-x { + 0% { + bottom: 0px; + transform: rotate(0deg); + } + 45% { + bottom: 6px; + transform: rotate(-145deg); + } + 75% { + transform: rotate(-130deg); + } + 100% { + transform: rotate(-135deg); + } + } + @-webkit-keyframes bottombar-x { + 0% { + bottom: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -webkit-transform: rotate(-145deg); + } + 75% { + -webkit-transform: rotate(-130deg); + } + 100% { + -webkit-transform: rotate(-135deg); + } + } + @-moz-keyframes bottombar-x { + 0% { + bottom: 0px; + -moz-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -moz-transform: rotate(-145deg); + } + 75% { + -moz-transform: rotate(-130deg); + } + 100% { + -moz-transform: rotate(-135deg); + } + } + @keyframes bottombar-back { + 0% { + bottom: 6px; + transform: rotate(-135deg); + } + 45% { + transform: rotate(10deg); + } + 75% { + transform: rotate(-5deg); + } + 100% { + bottom: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes bottombar-back { + 0% { + bottom: 6px; + -webkit-transform: rotate(-135deg); + } + 45% { + -webkit-transform: rotate(10deg); + } + 75% { + -webkit-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes bottombar-back { + 0% { + bottom: 6px; + -moz-transform: rotate(-135deg); + } + 45% { + -moz-transform: rotate(10deg); + } + 75% { + -moz-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -moz-transform: rotate(0); + } + } + @-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @-moz-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + .dropdown-menu .divider { + background-color: rgba(229, 229, 229, 0.15); + } + + .navbar-nav { + margin: 1px 0; + } + .navbar-nav .open .dropdown-menu > li > a { + padding: 15px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:first-child > a { + padding: 5px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:last-child > a { + padding: 15px 15px 25px 50px; + } + + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .active > a, + [class*="navbar-"] .navbar-nav .active > a:hover, + [class*="navbar-"] .navbar-nav .active > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus, + [class*="navbar-"] .navbar-nav .navbar-nav .open .dropdown-menu > li > a:active { + color: white; + } + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus { + opacity: .7; + background: transparent; + } + [class*="navbar-"] .navbar-nav.navbar-nav .open .dropdown-menu > li > a:active { + opacity: 1; + } + [class*="navbar-"] .navbar-nav .dropdown > a:hover .caret { + border-bottom-color: #777; + border-top-color: #777; + } + [class*="navbar-"] .navbar-nav .dropdown > a:active .caret { + border-bottom-color: white; + border-top-color: white; + } + + .dropdown-menu { + display: none; + } + + .navbar-fixed-top { + -webkit-backface-visibility: hidden; + } + + #bodyClick { + height: 100%; + width: 100%; + position: fixed; + opacity: 0; + top: 0; + left: auto; + right: 250px; + content: ""; + z-index: 9999; + overflow-x: hidden; + } + + .social-line .btn { + margin: 0 0 10px 0; + } + + .subscribe-line .form-control { + margin: 0 0 10px 0; + } + + .social-line.pull-right { + float: none; + } + + .footer nav.pull-left { + float: none !important; + } + + .footer:not(.footer-big) nav > ul li { + float: none; + } + + .social-area.pull-right { + float: none !important; + } + + .form-control + .form-control-feedback { + margin-top: -8px; + } + + .navbar-toggle:hover, .navbar-toggle:focus { + background-color: transparent !important; + } + + .btn.dropdown-toggle { + margin-bottom: 0; + } + + .media-post .author { + width: 20%; + float: none !important; + display: block; + margin: 0 auto 10px; + } + + .media-post .media-body { + width: 100%; + } + + .navbar-collapse.collapse { + height: 100% !important; + } + + .navbar-collapse.collapse.in { + display: block; + } + + .navbar-header .collapse, .navbar-toggle { + display: block !important; + } + + .navbar-header { + float: none; + } + + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + + .navbar-collapse .nav p { + font-size: 14px; + margin: 0; + } + .navbar-collapse [class^="pe-7s-"] { + float: left; + font-size: 20px; + margin-right: 10px; + } +} +@media (min-width: 992px) { + .table-full-width { + margin-left: -15px; + margin-right: -15px; + } + + .table-responsive { + overflow: visible; + } +} +@media (max-width: 991px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; + } +} diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/pe-icon-7-stroke.css b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/pe-icon-7-stroke.css new file mode 100644 index 0000000..44bcbaa --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/css/pe-icon-7-stroke.css @@ -0,0 +1,632 @@ +@font-face { + font-family: 'Pe-icon-7-stroke'; + src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v'); + src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'), + url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'), + url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'), + url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="pe-7s-"], [class*=" pe-7s-"] { + display: inline-block; + font-family: 'Pe-icon-7-stroke'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.pe-7s-album:before { + content: "\e6aa"; +} +.pe-7s-arc:before { + content: "\e6ab"; +} +.pe-7s-back-2:before { + content: "\e6ac"; +} +.pe-7s-bandaid:before { + content: "\e6ad"; +} +.pe-7s-car:before { + content: "\e6ae"; +} +.pe-7s-diamond:before { + content: "\e6af"; +} +.pe-7s-door-lock:before { + content: "\e6b0"; +} +.pe-7s-eyedropper:before { + content: "\e6b1"; +} +.pe-7s-female:before { + content: "\e6b2"; +} +.pe-7s-gym:before { + content: "\e6b3"; +} +.pe-7s-hammer:before { + content: "\e6b4"; +} +.pe-7s-headphones:before { + content: "\e6b5"; +} +.pe-7s-helm:before { + content: "\e6b6"; +} +.pe-7s-hourglass:before { + content: "\e6b7"; +} +.pe-7s-leaf:before { + content: "\e6b8"; +} +.pe-7s-magic-wand:before { + content: "\e6b9"; +} +.pe-7s-male:before { + content: "\e6ba"; +} +.pe-7s-map-2:before { + content: "\e6bb"; +} +.pe-7s-next-2:before { + content: "\e6bc"; +} +.pe-7s-paint-bucket:before { + content: "\e6bd"; +} +.pe-7s-pendrive:before { + content: "\e6be"; +} +.pe-7s-photo:before { + content: "\e6bf"; +} +.pe-7s-piggy:before { + content: "\e6c0"; +} +.pe-7s-plugin:before { + content: "\e6c1"; +} +.pe-7s-refresh-2:before { + content: "\e6c2"; +} +.pe-7s-rocket:before { + content: "\e6c3"; +} +.pe-7s-settings:before { + content: "\e6c4"; +} +.pe-7s-shield:before { + content: "\e6c5"; +} +.pe-7s-smile:before { + content: "\e6c6"; +} +.pe-7s-usb:before { + content: "\e6c7"; +} +.pe-7s-vector:before { + content: "\e6c8"; +} +.pe-7s-wine:before { + content: "\e6c9"; +} +.pe-7s-cloud-upload:before { + content: "\e68a"; +} +.pe-7s-cash:before { + content: "\e68c"; +} +.pe-7s-close:before { + content: "\e680"; +} +.pe-7s-bluetooth:before { + content: "\e68d"; +} +.pe-7s-cloud-download:before { + content: "\e68b"; +} +.pe-7s-way:before { + content: "\e68e"; +} +.pe-7s-close-circle:before { + content: "\e681"; +} +.pe-7s-id:before { + content: "\e68f"; +} +.pe-7s-angle-up:before { + content: "\e682"; +} +.pe-7s-wristwatch:before { + content: "\e690"; +} +.pe-7s-angle-up-circle:before { + content: "\e683"; +} +.pe-7s-world:before { + content: "\e691"; +} +.pe-7s-angle-right:before { + content: "\e684"; +} +.pe-7s-volume:before { + content: "\e692"; +} +.pe-7s-angle-right-circle:before { + content: "\e685"; +} +.pe-7s-users:before { + content: "\e693"; +} +.pe-7s-angle-left:before { + content: "\e686"; +} +.pe-7s-user-female:before { + content: "\e694"; +} +.pe-7s-angle-left-circle:before { + content: "\e687"; +} +.pe-7s-up-arrow:before { + content: "\e695"; +} +.pe-7s-angle-down:before { + content: "\e688"; +} +.pe-7s-switch:before { + content: "\e696"; +} +.pe-7s-angle-down-circle:before { + content: "\e689"; +} +.pe-7s-scissors:before { + content: "\e697"; +} +.pe-7s-wallet:before { + content: "\e600"; +} +.pe-7s-safe:before { + content: "\e698"; +} +.pe-7s-volume2:before { + content: "\e601"; +} +.pe-7s-volume1:before { + content: "\e602"; +} +.pe-7s-voicemail:before { + content: "\e603"; +} +.pe-7s-video:before { + content: "\e604"; +} +.pe-7s-user:before { + content: "\e605"; +} +.pe-7s-upload:before { + content: "\e606"; +} +.pe-7s-unlock:before { + content: "\e607"; +} +.pe-7s-umbrella:before { + content: "\e608"; +} +.pe-7s-trash:before { + content: "\e609"; +} +.pe-7s-tools:before { + content: "\e60a"; +} +.pe-7s-timer:before { + content: "\e60b"; +} +.pe-7s-ticket:before { + content: "\e60c"; +} +.pe-7s-target:before { + content: "\e60d"; +} +.pe-7s-sun:before { + content: "\e60e"; +} +.pe-7s-study:before { + content: "\e60f"; +} +.pe-7s-stopwatch:before { + content: "\e610"; +} +.pe-7s-star:before { + content: "\e611"; +} +.pe-7s-speaker:before { + content: "\e612"; +} +.pe-7s-signal:before { + content: "\e613"; +} +.pe-7s-shuffle:before { + content: "\e614"; +} +.pe-7s-shopbag:before { + content: "\e615"; +} +.pe-7s-share:before { + content: "\e616"; +} +.pe-7s-server:before { + content: "\e617"; +} +.pe-7s-search:before { + content: "\e618"; +} +.pe-7s-film:before { + content: "\e6a5"; +} +.pe-7s-science:before { + content: "\e619"; +} +.pe-7s-disk:before { + content: "\e6a6"; +} +.pe-7s-ribbon:before { + content: "\e61a"; +} +.pe-7s-repeat:before { + content: "\e61b"; +} +.pe-7s-refresh:before { + content: "\e61c"; +} +.pe-7s-add-user:before { + content: "\e6a9"; +} +.pe-7s-refresh-cloud:before { + content: "\e61d"; +} +.pe-7s-paperclip:before { + content: "\e69c"; +} +.pe-7s-radio:before { + content: "\e61e"; +} +.pe-7s-note2:before { + content: "\e69d"; +} +.pe-7s-print:before { + content: "\e61f"; +} +.pe-7s-network:before { + content: "\e69e"; +} +.pe-7s-prev:before { + content: "\e620"; +} +.pe-7s-mute:before { + content: "\e69f"; +} +.pe-7s-power:before { + content: "\e621"; +} +.pe-7s-medal:before { + content: "\e6a0"; +} +.pe-7s-portfolio:before { + content: "\e622"; +} +.pe-7s-like2:before { + content: "\e6a1"; +} +.pe-7s-plus:before { + content: "\e623"; +} +.pe-7s-left-arrow:before { + content: "\e6a2"; +} +.pe-7s-play:before { + content: "\e624"; +} +.pe-7s-key:before { + content: "\e6a3"; +} +.pe-7s-plane:before { + content: "\e625"; +} +.pe-7s-joy:before { + content: "\e6a4"; +} +.pe-7s-photo-gallery:before { + content: "\e626"; +} +.pe-7s-pin:before { + content: "\e69b"; +} +.pe-7s-phone:before { + content: "\e627"; +} +.pe-7s-plug:before { + content: "\e69a"; +} +.pe-7s-pen:before { + content: "\e628"; +} +.pe-7s-right-arrow:before { + content: "\e699"; +} +.pe-7s-paper-plane:before { + content: "\e629"; +} +.pe-7s-delete-user:before { + content: "\e6a7"; +} +.pe-7s-paint:before { + content: "\e62a"; +} +.pe-7s-bottom-arrow:before { + content: "\e6a8"; +} +.pe-7s-notebook:before { + content: "\e62b"; +} +.pe-7s-note:before { + content: "\e62c"; +} +.pe-7s-next:before { + content: "\e62d"; +} +.pe-7s-news-paper:before { + content: "\e62e"; +} +.pe-7s-musiclist:before { + content: "\e62f"; +} +.pe-7s-music:before { + content: "\e630"; +} +.pe-7s-mouse:before { + content: "\e631"; +} +.pe-7s-more:before { + content: "\e632"; +} +.pe-7s-moon:before { + content: "\e633"; +} +.pe-7s-monitor:before { + content: "\e634"; +} +.pe-7s-micro:before { + content: "\e635"; +} +.pe-7s-menu:before { + content: "\e636"; +} +.pe-7s-map:before { + content: "\e637"; +} +.pe-7s-map-marker:before { + content: "\e638"; +} +.pe-7s-mail:before { + content: "\e639"; +} +.pe-7s-mail-open:before { + content: "\e63a"; +} +.pe-7s-mail-open-file:before { + content: "\e63b"; +} +.pe-7s-magnet:before { + content: "\e63c"; +} +.pe-7s-loop:before { + content: "\e63d"; +} +.pe-7s-look:before { + content: "\e63e"; +} +.pe-7s-lock:before { + content: "\e63f"; +} +.pe-7s-lintern:before { + content: "\e640"; +} +.pe-7s-link:before { + content: "\e641"; +} +.pe-7s-like:before { + content: "\e642"; +} +.pe-7s-light:before { + content: "\e643"; +} +.pe-7s-less:before { + content: "\e644"; +} +.pe-7s-keypad:before { + content: "\e645"; +} +.pe-7s-junk:before { + content: "\e646"; +} +.pe-7s-info:before { + content: "\e647"; +} +.pe-7s-home:before { + content: "\e648"; +} +.pe-7s-help2:before { + content: "\e649"; +} +.pe-7s-help1:before { + content: "\e64a"; +} +.pe-7s-graph3:before { + content: "\e64b"; +} +.pe-7s-graph2:before { + content: "\e64c"; +} +.pe-7s-graph1:before { + content: "\e64d"; +} +.pe-7s-graph:before { + content: "\e64e"; +} +.pe-7s-global:before { + content: "\e64f"; +} +.pe-7s-gleam:before { + content: "\e650"; +} +.pe-7s-glasses:before { + content: "\e651"; +} +.pe-7s-gift:before { + content: "\e652"; +} +.pe-7s-folder:before { + content: "\e653"; +} +.pe-7s-flag:before { + content: "\e654"; +} +.pe-7s-filter:before { + content: "\e655"; +} +.pe-7s-file:before { + content: "\e656"; +} +.pe-7s-expand1:before { + content: "\e657"; +} +.pe-7s-exapnd2:before { + content: "\e658"; +} +.pe-7s-edit:before { + content: "\e659"; +} +.pe-7s-drop:before { + content: "\e65a"; +} +.pe-7s-drawer:before { + content: "\e65b"; +} +.pe-7s-download:before { + content: "\e65c"; +} +.pe-7s-display2:before { + content: "\e65d"; +} +.pe-7s-display1:before { + content: "\e65e"; +} +.pe-7s-diskette:before { + content: "\e65f"; +} +.pe-7s-date:before { + content: "\e660"; +} +.pe-7s-cup:before { + content: "\e661"; +} +.pe-7s-culture:before { + content: "\e662"; +} +.pe-7s-crop:before { + content: "\e663"; +} +.pe-7s-credit:before { + content: "\e664"; +} +.pe-7s-copy-file:before { + content: "\e665"; +} +.pe-7s-config:before { + content: "\e666"; +} +.pe-7s-compass:before { + content: "\e667"; +} +.pe-7s-comment:before { + content: "\e668"; +} +.pe-7s-coffee:before { + content: "\e669"; +} +.pe-7s-cloud:before { + content: "\e66a"; +} +.pe-7s-clock:before { + content: "\e66b"; +} +.pe-7s-check:before { + content: "\e66c"; +} +.pe-7s-chat:before { + content: "\e66d"; +} +.pe-7s-cart:before { + content: "\e66e"; +} +.pe-7s-camera:before { + content: "\e66f"; +} +.pe-7s-call:before { + content: "\e670"; +} +.pe-7s-calculator:before { + content: "\e671"; +} +.pe-7s-browser:before { + content: "\e672"; +} +.pe-7s-box2:before { + content: "\e673"; +} +.pe-7s-box1:before { + content: "\e674"; +} +.pe-7s-bookmarks:before { + content: "\e675"; +} +.pe-7s-bicycle:before { + content: "\e676"; +} +.pe-7s-bell:before { + content: "\e677"; +} +.pe-7s-battery:before { + content: "\e678"; +} +.pe-7s-ball:before { + content: "\e679"; +} +.pe-7s-back:before { + content: "\e67a"; +} +.pe-7s-attention:before { + content: "\e67b"; +} +.pe-7s-anchor:before { + content: "\e67c"; +} +.pe-7s-albums:before { + content: "\e67d"; +} +.pe-7s-alarm:before { + content: "\e67e"; +} +.pe-7s-airplay:before { + content: "\e67f"; +} diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot new file mode 100644 index 0000000000000000000000000000000000000000..6f7b58489c6fe76af1597fad93bd8ebe36114eb9 GIT binary patch literal 58680 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 Nxi7{(cl`%H{|#3vvLpZi literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg new file mode 100644 index 0000000..13d9709 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg @@ -0,0 +1,212 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bc8a269c68dafaaf5aaa7920e7a17baff0748360 GIT binary patch literal 58480 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 XVssBJ#01M7olcSaV(fF*fAI6)u)>;0 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff new file mode 100644 index 0000000000000000000000000000000000000000..c205e6fd3cae5dbfd991d499c7495c9228a804c3 GIT binary patch literal 58556 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 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-icon-black-1.png b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-icon-black-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cd702885b45d555982a9207ad95cb571016e437b GIT binary patch literal 15510 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 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-white-32.png b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/codemr-white-32.png new file mode 100644 index 0000000000000000000000000000000000000000..0201baefade8077c9e1e2a1fb4871d9e93bb471e GIT binary patch literal 1254 zcmV+_)5rR-bL6Hgy3Xl>B@e)fxkyMCRhmee-h*%*nHeeaY z9`DZX>^$zBd++yA#72p|JG&c&BTX@*Gv}OdzN_!v5f}oEMq}%!l>3G6&%pC`JLk3$ zkqkVq?U)yhF;}g%^{J_;WKd1fkHE~b*=!!%vSrJ0Ddlrg%2^@AB!H2%_XPj~P!Lg* zh%P(lzRR-gT(w%gB7~q}io6R^6iq9o-nZ5+Ff;LhAR@BXE-0l=udJ-h3~kKJUZ>M} z*%)(i7~?KM*cfvu>vUdWW^YjQkt9h@I_IK$HQos4T$Jbe8_ZlOHJ_WC3-UaFi-@xO zWxfs~%F;AFH8(dG^bC-u>1)op&iyuDhjXqI$MNf3&7&wfY^}ZVf0?ht7*lVxT94gj ze(l<|idO3LVT6dNaMni7+7=P%VcykBeNnI1M*+YGfT^jeV}204ILIP(*50(veOna8 z&!qJt0E|>Bd!+9_H>ecV|o^=Yfsn(S9yy(0%u99=km2o5xNFqx6XjK7h9X7zW z>FEc2-``foA?8#v^I{*ZNztcG-7q#bwqHuQvy8*QqGaYvWvdl{u-3|90|Y@ZE`;dW zUS?+J+`KG`;#X$w^mGRh3~+SY2+u1&e=u{*%)j_qmR%ShAHNLX$*x3TAprhi=D-+p zFbIN?5?uix1#l%vlAB{=W6PfB?d?W%&ixU`@dW@tp6BlnZ9aJs5vOVTHUOk)`n+>) ziJ4o>9QC+b&bb@ycKgVh?uR|5Am@30>c2E$7|t4FHth$-n5!!*D>L)+^CLx3d{Z`B z??j&G9|1tC)q31oyWB&iu3=881r|d(KuAA)jX}#XM>urLn(C{0OB}4>YQ6$e_j;D zxt_afv)O#a81p;d?$HMT5I37gopX(016XVSjN|xVtyc4tQeQIP-c^$%dAMW|17R2* z(^~(yzL2!mpA2ixyw*ac-UWax%U&&tVlIlJr%TO&+b5eij<++jOw;tRv-Z}#1X!#1 zO0={z&CFwIn(pK-Cn3|GOa^q zj@NE^$O{ZKecx}Cd6bS=W*${a9hXw>lTr@#mus!{l~R`{CMM1cA#5++zonN?TEWqf Q1^@s607*qoM6N<$f?TRlegFUf literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/default-avatar.png b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/default-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9fa88471a83781acf0c00784d5b4bad2ca487b GIT binary patch literal 2864 zcmW-j2UL^E7RNsVNa(R3EDs{E;vy)kf(p{hO4(f=^5CI7P!!!&Tv3qfDgp^z2@rZq zA=E&qp(H_qpaDce&U0gv&KxlE3GC={^K0?*Bfdpn@U|u&5K@?D0DU-N}QX`)LrgH2^{A zEeMK=g`i!q@x&bn+ILhLdBhEZq#^g;Jb(H0X|bpnmtRm+SX44SJ(HJTI5sxEwzl@_ z)xh)T-5Hr#TU%Qdl~r8sI}T@Pcng&CS%> zT1rbxYfUYsth}<8Qb(z)r+`u4(A3miS65$G-_Y3D)X>maN-8fUm6hNKRaNBb>YCyb zd__f7O-(Jaw5*`8xUH?7SV|(5RpjOsRDzR{Yw!djgTWvWOUuhE@r2Tb#wJh+)M{*M z!r_THJfWFNrP1iEt!?$7dQ)>-TU&NcUQTX)3s`Dz@95~r&dtxt$)nL|*zDY_?A-Qt zS_uwMqk~`+6cuB$z}~`~yn@WE90sE!6PuHP%}&qAO3%R7)YiQl8JV1%tgCD2c-F~e zc76Exv8jnVH#axGupkzTOG@zHzI}^{iHVJkjf;yzp-^ZvIzB!=At50#F)=AADLFYg zB_$;_HTB7pCr_U~O-oC|U@+zyKlx9zfymR|iM|nSX=^_hNQ+bv*}O>F)07>3Q)2DEyMeV)gd+ z_VxAk_xHa7P8t|^{rWZV1Dnkr0-gX)8V2IOc?)a-jP(w18W{yHdH?{B%5D4by0mTKOQ1}TrcyUoA5-lw)0jkT(%PT7@ zpFe+IU0nq>USD6ANF*B@8(+SB+1%U&X5QZ3-r3pN-QE5A^()|imifzG2$HLIakTS{ zZ>g;1cShYneyY;rmD| zR)yt|qtlYfbpLSAY+%t=sK3{-q&v8`Nvgr>kx$6!$Qyph@r^1)f?Kxp$QhL9P zR`8nA{$Zju#&>M5lAirvSyu!je%i7qJ9W(-1umC!;e>`#0!Js^PZo96G)cCR>~E$O zu4m^@S4ecw)pAyBA>V^5!p6M}dJ=s!5X%(%JyWb0GXh;3VW|uA{f2jTZtB%6^tx-}ODGdcb-AGb1hdzaQC%zwUgQWyTV-#oUlvO%Iq#<#)s4Igu!V<$T+

    *?EPk9lm`;XXd9~ zaIAjOWXqT++!j8H)Gtn)2#Tmw>rePaU4GqV$7JjK`E?Ya zQ26lEa&lcFg?({6H658CjBrHlgiN#1ie)ASuk*)SN@gF`AZ^e-);fbUQdp|6!vZ#$|3s%P@?xZ1_K-N1x3~BnKgytM!yw zTKBfey^nHJzQmo_pg`nL_MJv)H>Gr&>8>Gfc($h2;$f6&)sn!)%>+)MJKd5e?3nl7 zmJRk8XM3qQ&aP4`!^`y1!cD_KuF5c}1$SRdU7u%{gyA8}h6!6$Fo7ZH7f``n||U8_XLb`PWqSwpRo6k(j#;av4MfL8S7@ZREes6uMQsd3@<~VjixS$JSr%Eq}AH270sI zV7Yb=@j6EHgPEDxML)0Lit{IDnue`hd0wmr8f|OgKLg3|C`zbJXD~AE$AhUakp8w= z-zEivX%`1>nx2!=eLd3u%qExP#ky*$`P5Q_P zT@LRHS5)q;6pGnu;oM-*tk8Wkp0ZJHvwypVts=CJVEarEyt5d!;Iq4kzWM>IWR@_it}|tE->hi{|d`Xr8)>q+W*8w>O{qaRaF|_;X3L zbsO2IR`Tar^!o0@Wy`?a4usX>g-3J2QBg+|<^wQ7fyREjQ9gS+f~&~6>m3kah3E*^ zkFW2u-El8ot^|Dp?H=bOO`McjdS6dtzj7qfE~ ZLgvRUj{Gpa175q3%P($@6np=;{{!!q3-15` literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/favicon.ico b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7482a653daf1130d6dea4ba9a92259a8cf15c87a GIT binary patch literal 1150 zcmeH_F-`(e6h+^6Y={&PBZU=}F`+kc5tPKZ13H6^p@Xmhw<9GbE<<}0s3=f47yeED zB<=v-${Wq#=&@RX63=ee@lalIfsEBhb5 zC_QWKxW)+k?i;+XjI@1s?YN#1<@0}YeuZvETAp{6)sE{9@dLMR-X2&UQwsn9 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/loading-bubbles.svg b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/loading-bubbles.svg new file mode 100644 index 0000000..4020b4d --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/loading-bubbles.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/mask.png b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..429360d5ce730f002b7413fdb94bcd261339b5ce GIT binary patch literal 756 zcmeAS@N?(olHy`uVBq!ia0vp^0YEIv!NkD8cyyD`Js^j(z$3Dlfq`2Xgc%uT&5-~K zDkOUZ`7$u%&R}3D?qgv1b%ueV3kcwML zKmLP({*A-*E2LeiU=QJ1RAk@^Je8B|IkoT7jCe!ITtr_Iw7T7H-mN|a>_~Iq6)cxmOxaCz}U%#Ui=s2K3N3I^^Y%vgEy)dEq$tzzSg&VCE z-hNH8D(cxBVu|TZ(-bt7gnr7EDXw`FXuQACea6q3EX)??i)Ss{wNCy>i$Lu4wXeJG zt5is|ZI6GmcmLtk$Y+utw&ikeyY?(*od6RG}N|3)b--Fx0`gf zzb;_}x%SBnuxnk_#RT?9>t``*iRooAcc!mZnAfW+aiSt1qKtFX^3=I|_~e*B|L0l2 zpZ(T=$M^C9X3f)^UR!0a4SyS4G4HvFZzGFS$8JvPnb8pYyQ0%A4xY&>OYj9^0NMc%^60)#}<5!Gm85<1XFVdQ&MBb@031k3nE(I) literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/new_logo.png b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/new_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2192bdde5cb354dd4db5f1b7d55de774c3a062 GIT binary patch literal 3557 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 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/sidebar-5.jpg b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/img/sidebar-5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7471ab8e2fef9a071b93321963660f9fa6960714 GIT binary patch literal 280836 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%0A~`8*jGY*w~u8LamVc4oyy^`HHqR$qaN_oy<_ z(&|w>nOn{+y;6^ab_Ga23!xtP0Si$@t6-D36zzAHslNJV85?f9G>7{(65p2M^uH|~ z?M(DNUaxoRF)*?Wzgm|~4e7Nv4HEqDLpU*02<88>qXXV_#UYqg_+`i2+=njc$eak|H2pK1F6_z=AY6j{3nNn(RmTx}gy7}}nNX=?64_Q~< z8Ag;nx?PIkRIYHcE9Pv{1URdTMO|Z0mvHK*`?sbw^;8@q}QD$~{DL6(( z#J;xw#TaM@KX}T-tu9femWMT0@Kd7(uFC`y9TP$J8awq5;)Q47bvC7iet0Xbh zE^w~tjEXb9@Zta9d9QWiK1^*hCESKMgWuX;0d*qmF;n#r1kdiS!`qSCT!%0XCY;Sr zp2A#8o{6j2`?T6k#a1I`wRaLhJJHll8MEiI<+K|44ZR)_y7Dn1dm0tR;koFS*1)hR>smH=e-L;># zUL;-DkTDOWN}Ehp=nf^(lGe*h)|*6JrhbqUu{ve1%LX21Ctq$WXHGP}CC|l~<<y zUMwS)b2bbW$&n_^|Ca_ECt(Uqd}Xn${bNj;j4XhvBsuf$y%A}`n|+wGKv|X}MrKOS zG=p06BNl5hT`kP4{FxO!`29#v<)?Cc|Iq|oBaJ><4xTJq*y#8PlAnrZI zx)y9gPOTG#RQyHNnq0z{Cl||%OhYW5Em?lON|$N%=L<`lQ~+|H;DUpezq7UlsgQw5(IwA&cRjy3l5n*Aq?_Y^&U~slEMElIgLlt z69Q`*X^t-ap7(=~c3aOS9*xlEMk@?K>4xo%bjB=Qbbv2< zW_pr`)hgOXS$_Xhspe~cZuGX*#lX5LN!5rpn}{$w^i@CX5Y#3oZ?Kb z^5ZT-z6sm#Zz~5x!d+p$U6Xe*74xf0Z7s|{)s9$MHK(?z+?Ko#rK14n<0qgm1JLBq z>m)v+0ak|7GgTB=UFKTNk}L3~)1gQhUvHxh?=U~%4xMNtXwNvAWXUfdhWc4owWrq28;STPPj^~n(Nd&wXt}Z%U zj>t3I$-_1&=9eT$2+&j(4Ud${H~Dz^%?HTYhj(6%Ai0OUC*gvSgMNBLLIj10$@3Imt zE4sJC`Z72z*laa`dm}n_^Hq{HRs{iJj@-&1jE?6~)S z%B9@b&ds)jc7Uz#iaNfy%ZqN-HD7vM>WPMg?;wjm}3;%gN68WLTl>aZeml%flof2oc0HAMSTH2i$@d@Gt)?k)+HKv<#)G zn6gkmj~qv3To&!6gA2>@y}O(!&E@=UdA*f82FuzxLaqtTi&YrZhF~8GrYPO5TvRtAkLy2ZTLRAR02)SslW;x|0JPcCm za{4ZIkN=P#RUfAs_S4|2wU2T2WxE#XPUwYDx&IH$h|d0r#?nLC0=Ko}Jdt^KM*GYW zZ&TZu=M9t+Z$|E2`<7aAV zN`#tgjO&34&A6LgB=OR)O7N71U~WNNGU)5UA8k~zMyuOtz|`N4WL~KVxG}aBP|&0j z1WRRyYD)F|-Yq&zNy+?H^7FS(gR+?JAjl}t;{NM&13|d7rZ8)&KHaZ&R#DC-M~%SB zIL+$Kk&@BB|5nm{f^mtQGkAMxH=nn@q?k%m2Hn6OA4mzFdo*XJ)iX4@hc%aPzu@mV z#&|~klD0*#u2xN92w;Y}2P3BJomA$m48l%|W5o=!B6vT6Iae~c4GN0B9B8apRt`J5 zmCa>TFP2yi^M%f*C?!wqFX3MS0HZlshVsJ`x$sz$yUct}>o#NLH^EZs0F>c9;OCjzx1l?m5WuA99{hdQ718Wmq8T=72r#60Z zVo}N@;6ar>@DuSOgU6`+#GbCq^GFE4zam#1^Q!ZWYn3%8?s&mG?C?xEwz9~Z6E&Ic z;qv#f>ZVgVxYsNzF*~w|?IZ|#;Or2ftL&XMAE=jjYu-kfp(j6MR-MIsR->Xtkzfg` z(Tv(9YZIn0rgC&V^oVB<=7STb^hkF9CKoRer?9$rW$C@Ve9AsBe&~)lpEOK6S?obn z5vOxC{00SX2btEDSG)?Hr#psD^BgQ$PzsUqdnOiAJJ0I$+BvcSS=7bWK!W)17g2Q% z@X@MJ4q{vwfNQh&W@Rdt2@8o$=K;AU#UgT$PkhmGf3lpm&Z zC0_ic;+>m_ZG83jpVte0vVA71DlCHG0NjI_*OU%5!y2wRWid< z#J^v>@cUfpnX2c9_uL}EGQwl!!YNjLmgQU7TU7;PWA+{8vEw+Xy+Nb}V8u;t4OTXT2UY$AWziVne$aumyhV%Gu%kS-_vdlT*NMqT2ic z=ndis=_lLc%0|oAn?WmjwAy&4C~-7ytLMet)#mogK{byS=TC4|3RQWYa@JO!tDhjF zn33EvMHDOYx8;mq)85e>#53qvc+)}Y$%mFUi&4N$eHCszwl+ttz1X6-0wYesKPn5) zMjeDf(8Tf;!?y)4zXK>+aPs>p^v4e0ahN192qsRa_h3%tip)O++iYa>Ggc%6XbtBM zA27~JL2e&RAVPG&c-TK8s9org^(d_{tLajIhVCD^r6Yx|YN?Nur8T3UNx9xVZq0X; zuKCP`9a^2ns@`ia>c%Kf=+3+{%i#+8xyxds%kDlV`lKSvpxbozrM#!64uAnLlMVBa zXG~fx*1VLT%C5qtC98y(^Se0>HT^_e4PNJetR!2BH`&YgoE=q~84}a|f|r8OiW^QT zy%U!@41Y5OqH1)Gc`A+`uDAl}65craoCug?%}da&d0^1v8@IRwi04nOM=RyYCO?ne z=Vp3-sK}`i4Y6Woy74P}h~3a-4#PR$H%H3egREQmTyKS9DlDma0Gjkyo%O`{Ae*bS ziLx==&uvOk#T|-EHk3JR6UQICb8`Rb5`>)Sl} z3Hw6jGETiQ^}_#NvnE;RK4=%dt<7b5)y>H|TLoaZT+xWWQn6nx;*IC*5uDk zQLJ0KQ^$hf>vhW#bPP@_l|r^h@&*HnUMio>eySopjhy>R%26g77e9`%YN!aS+|@}Q zU7}d=T?RO*Q*fS|i(I;`X2#0$WK(`PuctoF)3|s3;ReD?H|)2^G2#-(!mcT@g>P57 zs(%vMxxyxkb=(z={?{nIpoJEB3>jBtCo@fwL(1o-Hx)hBi-O+y_gq10yuOR)nkoT^ zh3ZNK$$n9c#g99=%1%)+EMjt~g9oDos?J6q@kn~x8 zo>^CF`44^*Ij84k(CQ_u+xynMFiAfs@WV8&m_`DpQ|Q|#c~VoL@9M?g@DRE>E1fmF zHlfn>>Rs4sx~)v!$XPq#5~jKq6pteS)YFdY9W3~1Ts&k z1Byq6bAQ<>&{tC=@3ea^r4VBnn@=>ExaxPM@k0ZBQLBfMY|g|TzBe;}&P zQ0uw}H=fc+y6yIMD}=LY#;q1oU{L0q=EfyDHRI!=5UOn7$1^gNLZTkJXHwX|J}l@O4jnY`d~;!b`!u zZ3Jdjoq%TG%Z^!{ol~fNX17=W!s+m#%<~Yozt4r>Qq@}b;+2y|b#N|1Q5U}86-ElP zq@~kaWAf)M&j{yx+z>@`e@W}+^Yf_@Q}nG?8e-)siN}j35Z>XRp2`XNON>I%C)l35 zoDAM7fSJ5vRJ;ZG19cgW3|P9*D!66C(OO^EoHpE_Nnh?u%IOtQPkWd?llmD~vdW|W zqIh6u%wTA#s5ibEW2NlPXs}}JRKIk8R~_?JVMn2CR7*tKJew*7rwaDhA$4DWNR!TP zz)pyj!OquF&+a!nHA+Ievr0Nui{<6cpHU*B}lH%CUqUqr|U&kZ)Q5wT-RV=T!8!0&!LzNv4eMfJH zzpuAe0(Dunl`;sq&^_u+$$>0U(rtN(#U}yPc>ZA81TqNAMAT`%Te?W^Qbir`@N};< zyYj6*HqG#tPsMdpnv@W;7HGSzD*qzU_oTJC&e1Z*@aOBim^H^fe=yGQ)sNDoA|p}_ z8S4|m#wnc`+z0*)qn$wJSO-Z4T^vwi!ASg##~q`ivK~hjj;)fOJN!pe=1vPz`%BFj z3H0rrR2688_Y(IcfEkFvRMruT$fu|*xW%#1HEpYGlVZJTLe*nk?Q8`TTq+}7>L-yx zJogDj!#%X(p6AaNHe-ASJQk6uR36sJl+kkoo#b0o^^d4GFhw2t?0UU@#Ts72a*u>a`O_sIGHJ2w?_v3xBMN$+vuP{w;)u zU&y5^UwzNACn<@Q%2m@CTq69a$AAXN710*q8iJ!O$;N1z_Y}8Hux&dB;JKu9^po_6 zDuElX5|7U(i^;d?P5z@vj3wB4cF(ne4>-*plJ43#pA_I-j>mDpXH)6!mR^IpGO>Sv zuAPDmQbn#A0z#R~=!Wwz{T#^V;e2JIG8XSBa1swo^TRveOj^BavN4mD&3_`CP|cUv zW~0Bu&raoK_l=5N?_wpF8c1jv%|bUb+qS{Y<8scDapk_@a*aXn57CSlMw zo56G(vMPeQ*G!&U6CxQtPKo5&%gf?)WfGmf--V#ooG7gMu%g+9L8IGiLHtLHeJ96Y z@ftp>UH9Y4VT>Xa4uN~=9K&YomgQoQ2q8?XD&FdqWuQ?v@5@?o-NzZeckXBfuw-7| zyO)m{V{Ieabhf|gAr){##)>Uu?+=5BPIb0?gPnHgT+sMkcCCJ^clf-u-LWrrnR+e$ zmEN{SR3MG6#)~ZD)s+(_xTP(2lw%BOdG?;e1#5#@$e~k_&Yw6B!4EI%!|+R(mz#}Z zpB1?i-7d~q@J8F51zi)}9p=wIJY>9A@X?LIS9fx0UH>kVB})J|n=fAE6@Fr(qIe)_ z{PeQj&%er#r_xJAx*;b^Cpna)P$j}4Ce32|@yRaG-3e4y+&697>NNW=b5O6xS#dvaBv=byNhW?xSKjm#Ax?M{T?#4iifhDURupFz?k>2f<#5V zonqxm2}fSwSq4f`gr37KCa6Wg47ny_Q!{NOZ`_S`Y?iw!1Pn18%*%)aKJ3mqz9ifx&;QZBK@UP z`87pMnIF?d%VLXdGQ9c!X80Cb0&bUyi&g*8*i>kNv3g$ceOa@l-xCvNe*e&b!0CIB zg^!@6!cU$IQR@fEAGBKB9A7e>VSglWlp3w?AD1=U`0Vr07@NW=nQpSm``l_`@R0`^ zK+a9ez{zMDm!c!pKb$T`Zc)fL=l5zwiS_1j(|IyqD^wp!B6xfUI*%=+) zO6z$?i@go&Xk{7~&1ZnD_nOM$@VgI&Ig-mIupzq8xl(c4aoiC9gs2P~=8qp$NNDh! z2ToEB@1=@Siahu3;rG6HW)3{8&)2^5;M+o8gA-qRMB5*1BRCFJ4NF8jRo&e52~5zx zX|bSVO8>>_^^cT~y?yyiD%V&~HOaSpUytmeojw*%BW-8>%|=_!nb2AM-96JKZU51{ zp8}ry6*>ZAdJ%OfYck+K?PO4AeNpLJ+}Waf21h*Q=3|3arKy2Q+zkg`^v;@|kFU?p z8M-TEcENvcUxgNf6i9D|B17jZtreh{MT*=!ei$GblgzMYkpS;GW%WPSY*sLPmTgt^ zm9%Idc=<)r6yW)>CWqtg1EsspGxL|EUt9h0?BUjtwB5A*3CHVzFX{Obz+KsgB4RB` z^(fjJ@;82_{;?1D!?xiId6A*4rZle}L50?5)byvsgAfWqwyAYrLq`n2s zl8P1`E@_W_3yZFfE+0!Gg!a{>a!WfcR?p9LvByLN>Ab*OAh-59K*$SRq#fdKDQbz< z`R*M6WHmR;X&OHddiq(3@06{Q1I>?Ah`zWw7Q>7|ufi5L0n4=lNQ6Yz8}3d8zcX&NE-SQO&aerJJODYh~MBqHmQUMrcm` zNGIti^?d2mUu)84Jo;+xAl3Nm&C`7wBRl1A!^A@j zWesFn-}#usuQ8@E5FzwU{-iSS@X!X73@@O|Ew#>%!pmtj5Ccf;f!R1qQ&d7v_IlQx zkGCUoYHKo0>%Y=km+>19(`5DlHPSNDr!0JiZ6yc3)1(UC&GUe^n@6aTe8d{15zUVu zUwlvp62E8cAbe!l{qB*p)js)7dqDV1)>0RciBSH(KkzXueK=WUd4_u!9C}@%;oh3I z4tKWgx#0nw6~EqT)0F*+MEuk_vk9CcHTRQ!rDp`)U9X<>g#ajEN}s(|sM4L&=A@Xi zm^zQB-XV0s;+7da9v$8eCDh$O#}LiFh041xEqd6V`3Ij}GRW3-y`#12kZN#)@tW)o z`cmuT$M6y>!4l=Jn~zwkyh<*?JJLE2TTM}qIvpiu{&YY^pzVqVw?c)H1f{R{yAX@v zM34wY^O&^-57TYN3&p>mgY;T(FmyT^n0Pmp$OHyh>zS-%GKp)guD!OrH}xw}xNoU5 zI6nsxz5(V?ahz^!%tL&m0Jaq!bgSs>rt-PnXEX3Y#lI;2hKcXm-Lt zStQ2Lci^4P|7gx7%Yg)8&B6q2s^}v}9EK5mq__jMgI!q+#GEJ*n~FAn{qYMb)h&K{ zLrc}!OJ>=`=}Ww4kwamtux++T_K!sC{L#(TVIfKazdh-7AiwW_H20t5@G@xp%eXuM zP=axW?Lb{p;Y7NrIq2^xGK-ovQK@3Hm48Z>K1s9F)U%FRlXh=+*OoSU{e^RB+er!3 z9YhpFz`EmPy_f^T4Ny)v-v*4%6##u0BW!> z>2|d|hVRlRroR)mSKz|K#(asEQ#0y9Wy-U_npA{Zz{_lJwDP+0Fj0Q(%kDmNDHx#& z{PXwv;l|kZyjwm+<~5Zib%|>^pemR+L$G}YBxB%SO&ph(*rSrKnk43;`k6n(E2e2* zO8z>mL;gmA1MLhwl$JXnbw}|UME?|H2|@;{QEsd;eXOXB5e!i&=_R9SvGkF7cl8w|Ck zC2<%PlLqHJ<_32UrU_f7){m#pji}chu{kPA*vXc{L0-gOX>oz&{cVYid#U5lHXndu zW=CE$Z#TVbpm1E(c^7nN3(cf@&wOiEZ+y}s8vY=YqkzYTzN zu(9DI1%Euh>kdc04D+4BZxhYdBzEJlN=$6z0D|gwSKdDm@6dHQZuT4EP%fty%n2Yv z{gg2uSdKAM^orhDAHB17!)I~uQAo7fgz=RQ=kI*{Fdd>MmZ`Ig5#zspepFSkToK)B zIT+U+f+!a_eZ0`Zie~8@u6ba;rNJKdYMT-|=wa67e{S~<mX;`*blvI#Mdwl|6 z)sJZ+ST+9qp1bNinU1^cBiGR~b7rw62_tQjMg9?{H(o)q?9&+{3|)H(q^3>rg|FE~ z1e&4rpRjYMr2&)cYIl09CWe`>S_|oM5$-}It;&~k!m`$3ugN+~lhK-s9>^KHKSwgS z)IC=G*6p-_Um!+qeI%;u@Nf4?+e-3JT+V^;9ak7@3cG^S`>M5-?P5Z zvA3-hMmuhFM@ri0UBj_p1T(d>W|R6|3D9spD1BeWj7rx}{}Dsj~aw~l5>a+M%Dgd-mOI0^tZ?qQ^#+ueGgo`VH$MY>jp zqm(syk;%N!QQK9ucnPs1HL7(%X}Vz~jCh<}gHtw6_0ArZEv5)ipZgRz?&CN^Mc*Wr zvqT;JR4>86iAV9@;dwlBTT4UV6HtER2>wy)EcNL@b@RW}u}C;@iJy8JVrarPt5by0 zeNo{%yk1lez>3cI)K5#3+^BBEpmPt38{!;@nm9j6UaQ z(BUS7k>SBus)$MK|6BJ3+BqfNQhoqF_grPt1VZYBL&DzB_14}SImU^Mi{56)sXUFkG#1J^yV}E(13`M{ z9s~J$9o|rT;#1qZ4)p=P#Og~&7aJCIyj1;<1Y53~w1ig)is$@7+i}WR>5U*|k|A*@d^&{L5~p3gKrH!Rn4ePW+{hU{cWH5fM z$;yq%|286ddF{Ce=HkG0K7N`)Y;!X<$%<<&?~OzHZ=-~kpP7@jqyL&Hn};i#V^!>H z(~-MSAKk#ZR#H#-F1px*B>C?#@KZHwD<6)_o=EhDDE_#sN2|YRALOGYiup^~)1+&y z5E&witQhcwPxB}zV<934Q)911+xgb}NTYxHx8IY>hf%?G34lDboJuo!>>s_|E`d;U z7C{uAGO;-No_74cmGg^HHDeQ0gWmn_OM0@fWNrS>Kc52+i?KiSyZgsed9s_m!sTL# z)pB}!+bM6WXRU}VMx*krCB0i3=~WuibR_ZB1eKw#w0K-<=XvS!N~~vY_<%kCDs?<3 zSi`Oc({0hW$ zn$=BB-dwO=&>GW|fn}!t`D5P`dDLM-NQristN9(G<6Tp=@}TZup(|^hrh-DATc?y#e4CdhPA%cA$Zd<)X571iH=m z8Qh%f*zwns`rc!s#Yzzfl_Gi~p7|NlR(6j3M{*=3~6 zGLvx{FC-xu$3B&0oH*IrNhPvQ2-#(3p2V@8lN~}C$96c!=5UU29M0%__5S>R{&I6& zZrAfV=lOih`{RCZYJ;6|=8R?E)iv5Oan5#4{?V?o)SOE5t545ZTRQYW%JLDRfg8J^ zj9D)NO`LL1N$t}@nt$3g`qqot*&aj_YP?{$scb9@G=;;PTv9HSS?pr*ms?gK(2VmiTkHC}gB$fOxvg{+K#jl|nKfM__ zu)|UEh6bT33&sS7Y6wKy*6| z9|FoEmVM7b-6gf(pwaV>1J%MkO8(J=e&5T)%Nqtp)^2sIu!)fd}1XOIW z6`?T)kwk01w|`lTA$FSuF*#!x8Rl&{@9F~(oj=skkottgRaEm1rrP%NhbD>4!-{wU zIh$ZQXLMu46KEq$K}c3bLjX?dl{kjKrDhW5zNEWi4$FZ!pKei zLVzVsDY`T$5S(I6b;o;NhMiR^kH~$Nsa|oS=$Fsei_JZ9ht3z~Y|VU4ZAyCxBa3LF za%rC2+EJbk^x);hy1sOE?DHw^<#mrYQ0p?#qM#=LFWxU-;}H%b%qt>drj20l=B~EX zTAs^+F?lWcH{c`Yu%!#pw6{$4B}^^i#}y_wHL)tClvKVsys3tz6dbd7;#-Kksc zl@SwFQOS)mdn&i_w0K<|8qfqG!Nv4VufH^-4|3~zOd}~S^(+5$S*I7QYdmr#zr!}0 z!w%P|zI#=?gG0UqF2|Mj0UgBIi3RvllRxoiS&1DC-V0CS|7Z!HuOY&za$cn{Pns7o zTyJgx+xKHT0u#`Pp(+fPz+f~8P9g2A$;IJKW`NFLmhwu#q{|Hed^6Js+17+;<{O7` zxa zq}!A3e1=O@|GmXQE6{)-JqDZ1n}B|$(OwcZ2P`;x2jIzSsrR}C8Mdt?BtAQrcMMPv zCb~o+hE8XfGqWYUA&z0ksCk9dX@`-iant%lmt2sFWJD1932|r?+=JoKQKgh8Pn+>m z#y6vBSKR?A48KzmiedL#Q#zREhJU8D&$tqWo0I#FM`@=9dJ=a-l}v)PQf<0Zm-i>7 zQLyg@$=;=UHrwj}igpgt(4+2yj5lUUqG=5Am*dbSrWiz%6Fd0 zPt0S#9!!%AduYqH@2*?kx0+usw0+cGnhO}P5?yYL`+lcZd>lP>r?tKPA=8m@dGKOu0Xy8cG%E) zJjq`85vC3@?B=xd_UU7n4IB1~81K+>Gjt(FI$Aa;b673eQ~bc}gH&GHt!JEl5oMjO zbJf2}n-XiEjJ1VRw6Ea53~=n#goj9ciPcm-#HZ;`iv`1fAg9LL;1Yff&;Iy_nn(2M z%<2W~Y)N|gXk>e>20O$eD3J^#U4#a51M{wD777Y~ycbrfF?%p1@BPaALrzE?NIZ21 zZdtJ&DkC^B)zhfpDB(Kf@4Sm+ayG+@sLqs(aX^W03U9kmpJ^@29(pH(hN5N#!8uN$3>Ow6E?>?licnYwiAG#pM@x=o*lj<``t`D4=@yHX`6k~nD)`)j zqMY%x*uyKHbA}~Yj7`6bQ|g6BDU&h>Qj2m=NXd`B63PQ-_ah382^*GL!eU6qK5!Vz zISBId=?-fF&bkpWCd$JNV7hC$T|o^nxz8o>D6{+0?o3fltoX0f~a)Y8VvYN24rupO=4QQ$Dh_{hGyMI4K-Fw;{+yFvBZCl z=HWjFJWB40Q{M~tEj8f%vP~*ceP*!d6^ocrRbY?AcUTwn=cF@9ITmzU5H#Gnx_lu_ zT}G%juaq$IqiOh0bJ(C@4_wsKJVVd~1?%~@Jljh8?Kf6A8MV!ht$+pG0DoD>eFH$l z(DdhetYk3SZ%vCK7su?t@jZoP{Xok}9B`%6<%dc$+hKS}h;HVMQ;+OqsoCNw_)v?W zLU)alfAt#cm2RA%9U{v5cOBw6+GW@`@7CPdh#RIF()n{+Fz~g`!Ysw}_Amqzh}4rEBWA8j z{Qq(L*S9C#bt?P2lq)QEXz7PMlfcwCO~Qbzo=4FwCJGD%CTA=Hm2z`iVF#DJY2Tsi zNca=|@WQ7RVSZmkfJr9MmEUBG_J*(d4#K%oLs$$y$SFz5N4LzT$$}4lwDyNIR_K2z z<*HUm7dBta!;M-=sMh7;z$~8k+=s0^?Ah5bUA{0}8Bs}JKMA<1F-Ly1%qm9uS)KIV z2KfDq8~mbU8h;G3uqGRA%C93P z-z=c=UZEz=X$%Bkho}TNsDAK`TxGAfTkRO}@^DOiq3?1^bF_^bJzq?U6n5{)aEncN zlhkl!_Gr0f*;DN>J27=nuscW5U*at89_XC~K&LrtXfXB53eLGzTHbuaZS=ruP{Urw za0s$uoBpt-ZXuV;f5&ZeV^{I%y2fPz9dF!Jb#gd&%umFB;YsuUdzBYt+@>3(P_Apn zb#`Ob-&M`1*u7^nR`F$aN4f7w%0DuDx*(!!P26!%nXS^Y2jA>(y?t(=xAKbRL~;;| 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
    (rZcrY@enMMxTMbaQQR$2$pm%`uegL-%Gj)9hoS zPR2lIiKA2iOSLGJVb#o<=K-XKQ$lAzLi_U_dAh!TS;7=U!5w~3Xwh_o=OTfOH3l+;`$;Gu&k#Pbsh8mQb~g8hwmxZy<7n4J)$x16L%?-zCMEsmcOe68V78md~TFTd)DNR?j1|G@%jdTezo*{ z%~33I@M;!7URz6jdQM}#&{#&wU-QJdy;3a+P1w>sZY-qI&4{9KrFc#c^a?H~H{2=4 z2lRkJsr`wfJ}e|JHJ)j_F@U(wPA1&OID-1^4iaW4&zF!UhH>eYiYxOG67 zYJsU<`*Q!^U5PF;)d9DLHyIJI74uF#7<>urGVGe%J^Np<+rcw0QQ!aU_}l)nq(P{F zVGv%eG$=?Nb?PrkR*g@s7dqQ@uY}9OFn^W}uLPQtAXq3x``u%VGj%}SAKk2gm8v)p zW~!oPj~CygmUDb@be8~#hTV|r!Rd7UlSW* z>KX1;jDP6Y92g882Szb}*rk<{ivJ|zE^6;51s_h&)okhTl-h#^JV(aH>CoRttzdpP zOk*w_6|FjUA<*}uQ;2_AlW}e4CM%;#{wdIxZ;HH|6&5h`2}7{*gLBW?d;IQ|wwJn_ z9LUP>___dl4(GQ~9Ro$#TaH_fYw_IFcj$MW%RM;iZ+kMYa z3wL3`)WR1vLVPvnsryxSYOYRB!`Hpeg}67bGXwzKT{Um{g>ubu+(`Wpy!qD}=sDz7 z(+W|Uj4&i6MhT-Rv1t}^81;IDhV6HBxYwur|ltQ(WB1&G}s5j`qqqKfR@u-J#55-O^00{8y1JZg@u zub$~(29E;_G*SLqD8~VAVo&zZMo^`d@S{#kt4ChvBDS*7-w$7)Vb%Pyr+U(kTIuPq zF*@QuQhc2E)Boai+5>%mbJA4j7jHu7=SL{dv+#AO6YO~QgiBBe$HcD^|3bs)e~?7> zMegGWf;w;{NM@i(u?R^jcDqYlH9-N8W>*5$tq=EKnSMF(^g}|4PEtx@hnNjGgE?Tl`_EFhJ`c3R1Rhs2GNx_N<>C8CMw|6A^+ zM^=r!L;;Ru2&2lX*T?+=@rSuQuNSzgt?|Z1Nk~b^_D{(N*ZgnoueGFfujh?EpLXFX z3Idu7IJ0nViXIg%QjB%HtYRqYGqwaF+5F>3zCzWfY1`XUovcw=o%Np1{yy;nHeWaz zU!VV7f5-5~K!kIm|E|KHh3WO-9pj_JJgcZw1#$N210#&aP!?c+D{&-?eeC!{Ds*0( zgyno7j4e71@A)(TN$LjebG$0+uAitY=+o4@&*LM>zk(0e?3yTXWloOuTksu8;P6M9I4;t@C9-9RUgZKU zE0U$UA$MKfwx!n^w0|O{z4_Wx_8VQ^gaSLhMt8JrZy|Dy`OKhF&wrrIelk~rW=+4+ z1O$Fr52?OIGk0M{tLrI{Ic=hSPI<$Sme3(MfS)b&v4C@)TnpLj&B7=&T-g|5m8{W2 zNz8W;(#4*9T&DY}@yHLLJtL$pw<3dV{f#asuM@h#FvY$2K4HuHiRw4G({pzWY4WS` zKS2wp$21p#z;y9n3y_!~jPoGwdmN#W+ghuA+??Cwo4WFN^@Pr8e-PJNz40r=3dVVaB7HyuZmiK4{$Q$_Wu$MhUxH9cWj7vH>NmHKe& z@O_w2>3_{F2zm^L;D~J7X5SEImIQyU2=&}=w&nlWl(gKLpkOlo)t^-_eh$U|t;%mk zuB~C;l%hOkpq!~vk7NOWr>(~;YO};NyE1<;7;OwWcvI^mmXGD z=-y9cU!#tg=DQXX^~zDjGnDVOkGf~gKYqAnXt z*;-1&&a13w5hTrigX1ISrcNfJ0Iskab5f1{-0H!&kvAWy;ndcjODRGZ|FTrzoWyyi zo{+6xdN(H~z)I2&Lxl127CBc&o0i9PQM*8|Vg>|7MyD``G2eMQ;G#h{@9igOw`E=& z-v1;CS`*-I=Bv51_^Qu0a)fIniR8k}^;Gh~DNP-~Cgmwn`pJ=J?D`XcR_ga_j*<|#vvfQwwD7Lg*x8N9bKcBJ(WmxmV#fLeB6O0uPQ zA~^A+xo=zl1ePjt;Ih8$x-z-Rc;NC#U3axL1Zi5n@2IP>2%pcD5Tu`X0USDBumdgx z<)sGj#8^`(l&O-`WqmL5VK%5ZF#dexxU_#2D}WM@YI#CagTB`&@@jhb#{Z&#UDp?! zr{9h4mqvGo47x*kwUAdDNCK!LhcIk2kVKlCr$bk_Cq*dT%{TpFP}tB9^F()G+Ct`Wb4rQy7PS)6&|c%jq#wmPcrZhmikFQw4bntww2dfUC^ z8hacp;V8|`&;{iSbZvmVrj#_b?zWe)^$5Fd*!W0%@Xm31Vo%aKcL*tzJBy-8%Ausw zF4AArr-^-cu$w&9y|4Xk_(&9dSzAb$3Wu7mm3C>bjx2*A?|TIb)H&2i_2>kjR`~JM z$`YXZFrS)xF<#m1ygr>!rOM=ZvcsHUim@Y8|1awshp?-hUNd{ePKye(5Np?hA5<=?Y*sB%Vs) zU1RhhhcPqo)ovunyLOLWzB+WCIp}nWiXullz3!en_2k_S9>2VW_e-1`J}33uNJNLn ztB}OzJ`S&5dF!tMbp+ufvNTE)sw=w@-Y|Dn0KM?QNPaEtmOM7`^4Zw<`tOsPFnd{8 z#t;Ap2}QO_XnZK&^=&MznGEht6+IdcCjd?Q-7X1kx{-h3dZvZlx`6U`n@qRCnOC<@ zTt5Nmvb?-q0ixbg_neOC8L!XGBRHCe_1?dk-&$)i(@#pvTxRMd?jN0|nefyw`$6pE z#W?O6IFXau@gwi_eyP73<~IpglrFG|wjfjW9rdSa+F^1v0D3J{{EeE6j~;m^2q}9F zPE->F+|RIW&i(3CxwLRWX6ku-dGLdJOhR}R?Mzo5@VyXZ=T;1&4;{d-!xR`f`$I8k z71Z!15&wQ!VO!yQS{Zn6&HeGF~l2JdOMJ2^ArIk6>HT^9f#aCVFsU0*^(E!`k@#sfa%kcR0_dx;(Z- zn6E;csOqHU?GCi~Zl;cUM;hqb>J2d_YBJ+anmi9W5gV#DLjTiOJ;bBr0`;al`lakz`VfU;rOMi ze`C!yr(>KOV`X1H5NWD1>J>V%yFql)6Gr{Vtc(G-ZXT)CH?8jPiQV^;m8g6Iku!1B ztgvsbII2`zZ#uXJ9O3d%MW&|RucWeG|DxN{6$RqXJ}Ph)_63OKghOzqUIS2>>X&9d zM|T6Kwv-yN3#RszWCewFA&er;1`C=)G7km%+v~A*UX^?wJd+proyDKhJI@39K7-9W z_Kf>^Usj!qBq}V&i4i5IeT;8(fd$#bCI+GTDL;<#MHwkT(p^FwGoZrDOs;}legfL0 zrA+lT>3*vxv%FMSyi)1s0(~ev*rOtlKlXY2`Sn}sbJS3LNsO|Bu~JQ$C*&x^n*kj< zzksb&Z%=|IdNWZVYT1^K_PpbxaU+S;Ph{4!*ntF~ zPpJC(o>XprOFffwoaR6cwIu0C@a&lwj9a#3u6g-uL>?5C6?0x*XnQWJBd)QF#oSQa z=7C!4C^kZ99(jaEJqw;5J1fie&xh_Vmr%#!%-*eybTQl^p+#O8Y)^>}-lrqn7UhWy ze-Xmo5u@MP!Q#@4=x#ZU|6mWyLiHOSn2ZpQxaC*#js+Q7R}W8_)et8|;QjvrZ*zFi zDb78nV=?5#1%O2j_{GX8CedFoPNOAyKr(%C{uzLIP7aBCiEPE(E|s@|IkP@4G-W zexB~pnrb?c`?a{jkasBYY0;g#F~q-1M!&B+!aj}+qB=U{^cqMS(vaA7(_BcjYiG#I!`ZG!8XFuKKa5Sk|ldQS&utch!{|P(m@w(+_s*lzX6weaHKh68g1@8beT2#82d1wl%rn_0AgbO}>wCMg}8iiFez z1SDi4AQEHJ&5%Y?YBIWWun}Xh@ca5)zw7rW*EPn&^Lk$AIp;q2x$ob`W&;7%1##N; zgZq?8SRDWMl~Os-XJT&6#CE7&&8MDR(D<=g|+_q$DmY6IlX}7oPtT8&eJa~foqU> zrE=H=gtx}~nnwbm<{%c2vN#aPVY-)$HhSY1mSP-w3@9`rb`A`~I4piHT+h+&-Px z#ZH-@$z2!TH+)J%!Z@Mx{IEN2be@qHDccqk>-%|zl>2Rx1A59#CCr=~EWWkZ4B?ug zr(ssWSU979HlP{rx|1}gIsPpP95>I79}pC%1{(HyHH_<@k9eG&!mp?TosG~Ml-1u~ z+F4jP^!7Jf%&n{D$QGc9K9Pwen0P0gLfSCVILHnVQ32R#G+gNefbU|$%v)|d;fzI@ zW04HyI3HYL|p6{~6y&=Fm(3m1p#qxdaB+7rD$q_`z zvPt?ZsS2;0sNn%aL8egfZ2uo5P@fZwYo;jzR87#)MZ`(gNf4d&T-w+|P-I}0G}Ukw z;9Nd~ZUIR1UqEJAjSTI zxc|B~K_k?VEO*}3)*$NE0Egb?-~+xje3sq~c6+6x0@u!*Ky>Tm`fx%D=^=PhsZQZc zx?#_83e5iiv=;;m5P#UM(b4ct)_s=wVSR`ky`uiOI6uX>WlirNL&VdUZO2y$O47fZ zTA;;xAO21f2FH4S2!$l6EUaPN;GR%pGH`(rj1tXE{v1E!L&*+X#P_dM79<0hRZ0xC zlxSr*%hjHaAH~>V77)nlu9z;+yA-O*goEOEvl?H-7hx5Ob3ww+{p235V>c%g)y0;5HpAi{MUVqQ$!HSoQ&~Bxz{40gd}vMgpCtKR`g+hM01C_qw=|h zoC~HGm)9lsE&%$4R`p{?S|e*Nz)U+Vk3U7yp-)xpGI-uxs7M3)H(Ep?A78B24fOik zTv?PGp()?0bS`=AzXFtgq&4bz4~^dt?cG&p*JCg2Rc=^TUVAwcQkk#CL`lIn3C7N) z>5nZ=rnxs9Npo7?F-eQ-zU1}&bnd(I!Bs7|;zuCpp|41vHtYt~tN&wVfM$ zrk<)-x1R2P@u|_7?I@GBvpIvd>5;9oUK}YK5oZ9f<(L+yz=ne?_9O|{U~i5(B}qVa z2P&#FMIiF)m+yi78J8VcDCXfx;B$1DZ3k|IrKgR*yXA#ObD2w!ml^H5${idnVOBUe z3)mgF_7<|Q<=!AiEP*Z$lH#p3vCeRI5K+F~Y3SL$dZjLtIW^Bm`!!-10}8HP?^Zop z%L}-fwRLKhYr{rt;!i!vA`;{}%{z?>kh`-Dfs@-|R18NUufB|47;e75w=4c>7WeNy z019}^dxV&ZA(ax9c4n8SBVIpj4S4?W*|dJpqcD(v0A1&YdfdJnDs!?x7dIQ@aU`y- zaBES)e}EKZhxDh0(Q*I^{7b4*l1 zU7>~I6>N!pOsiCP_IC7UK{a|br7M3DziXk_#?Pt;P7ER27$tg_^v&9Cwv4uvQBJ_k zS$I|09|;Ylx5X*C{*)JY0YVl*#zq@c6Gr?sYP+7odI$O_AgZ5Q_N~!=Mh%tp>Q#g* zmD9B|{vU&xBqM;U#r=Tw5_f4I>B?ez?oMFhW@%s9KZe&<^j0)YoKZl-*_hsfp@}?( zIRUKa2z2e*EWpv04^~+(3+Mz|vUi=50RuP?>t0|_TF^&5@cy<`P(Let;j`cklYb14 zB;iA<04Zr9W5kivPS_383i@9^dqU;^SIPPM@GhXG=tXzlWA-BMB8aYSjh;ipoWYSM z(d&k9b3{q8b@gclb(cFCrmdCFC3f9YL9_pXogdks{cU4beQ5VnXDt2q#7E!K4wQwgVX$^nXA z>SEA{Wr@Janv)T=wlUdXE+HrPEl-A@q;`k09^vP?z%FoRsu>}zH6z4jviQYWyD2@d zRog#Cs+SiKpL||BM0$_r(j@j(Ps+tn-kxGjhgk2&u;fR#+qGjVR{+Fq5n^)D^-+O=d*N*Q-_(lfTMT+9LGQ)-7ILiK*^|Sbjvn<%?tW{m zYm6eP-z~Ja8%e4;+M{v_LW30$OzNJs#G5%4kY;ZGFu481qADC8wcPI}lo(K$qHES~ z@Imrx$|7TRLexJ7{x#rQl0-YyT*vAu-9{ZwxJTsD5JRsoYlw5L$23(tAR+{7XFX?* z26?YnL;ef)UZhtAH^QolH?Sl6V~Uz>V*{yn-RrgZFT;Ya3J3Ea06~Oo9pZ~ImobGq zN9QAuuIyDZnt!*C_{}mb8nFR9cgw%0FRcYi3s)+x`GuuAB!8p25M8nt(LWz8v6!kU z*ng8zInnv50hqmvbS!Sam{(BK^t3;ms0F&n&2{RHf3pJQzf4qHVhwJ))_DRu299&! z&F+|EBj~(aO$}_w>j{uLWt@@9UD8T^*{gip1dx!pcB`V?OH>*RI{w15I*Ui&4-=yVtrlWL9O`Hx*&23t9T_T6=MiyVHH}+ zh+9E+UQ?9m6Wtxo7S$M1q-RpMX8{I~X){~^@7v@}@~nGAKMF7QEY(|rT+c3+MX7(q z4*`DXCsx2SCOlORpGO345BC>Mzdgm?j*v0W_=F*i{Vg)iU{qKK(dvP=@j}^HAE+nZ z!ZKNh^o0K`V$Z6VBz^ObLhZch@8spR%|0{=_)sYxi6F9_tQXn=U(|n1aavssMQ!-4 zMI8)S0oa1bys@OZNpX1mkutOgxtl2hcp)Y}KIUfcW&>t^4}(!!Zwn~>hhJ@?L=`p; zxbo}_+}Q?(MIn2<^Qz+?iqbgslE>E6u^K_jk7|r?p+mul;3ioH1DV4A z`#zW9kej}gKJZ??RgE{GfvG&qrL}Cyr5)GlvSl<3bST;q?Z?(Wa?w^YhhQfqiQcV- zQ$k!}Mpdp~e3Po})ABZ$eHDs2wu{rPW>?>6I?iC+`>^=rsA?UhO1)P`W}!p zoRVxe5x=C9{m9D)_a0YzwgdUG;W*OmBddckWn(;1&?@Lj!1v1MyCx@=;REABu0wk= zfX$40A2Ynn7dTW3vX9H(#@N347!n~~Zfwe3pAk%34x>)+%{;l-i5Sl3{n%CQ|NT8~ zW^Bz_f`d6zhguD%Y(?ijeZ2;z9lHJ1ALUGrE3MQ{PfiN&1Iua2*N$m%OPDPNtQ8tH zkGm`GrW4yx)b?hgFs*PXqWe?K6ZJU(3+Xqu)BW zLi>}*B8^C#=yG%uOWx#fZd+ko;BT_9cupcj zhfp4KG5hI+^PR$2W{x|O`!e8mpyAxDnl+jRcI6gFSd}4<{=9l;+B*Fz<7fhTA6Sqg z*m)MzeY#sje_58#qfj>ua@`fuI*lDg1BtDa3x`nKPbbm4E z;-;YRE4TQVr6?)CXM@f8S;K$|$pHvx=RxG-{BQ+AQYwLSac7{FgJ8^C)84v=hb}#; zaKx_obuJ{=FMo?8=h}5=J=xWOsw(BQR%py6+vn50gI1lMWc-DImHsiDr4DP8r3g*d zjkUu8FtaS}HG3dcFIG_{64Annc#o41eJPkCz&zo-f_<+1*cQ z`b!j_pE3YyKhRIvbF`1m|6z`p5(0)_L!^Pn0W+F^C&&gqx|V^V$)JmXa!*fveu}wG zD!1_od;r@&Pk^+-E(UAdAHq9417M{m(1V;hx(D0Q=Hp{^($ zp%=ka@vctTvwkehtN9!30CLzXo*PupU#7&>2tAd;be&A@3~E zPS5q*3$ExqsSsck&@Jw?EYi;@u^?OiV^}>9O&ii@pGD?Fs)BkFl}J5gUth;1X_jgc z!`cj!XLgyA(tnE`S1Yb7q(V3iEJCfrh3Mt=n%aEh#f zGRuZ>{dA@Wi}0zlU8mmfso;X|#XsEYDHhdiD-WI*UieGjyxghiqZ+gxcVfJ}PQA*v zgzg%?`e-SU_w?YGs+!I!t}{RxpYozxm(^-uC4k`wo!s%Uj$OgrQ+sQvg_s78X1 z2dDNh$v`V?P@DW!(l6vWgYf>tw^`KbYFY_QB{*Hk*L&I1(cBI^clGB)e!7-mtGQ=A zg3J=yv%^I(3%(Z~3IL3$ORt$D{3WtI?H|7tPQP!FQ1KPVI;y?Eu#$3Vt-5QKJZ0w1 zX)&Gv8wm0)Ix4-FB>OJK{Khv*U6`N(#Tzzpx`#Jh?rOz6a4h^AZK(R|x-2f=b2c47 zWz0E@N1j_n;vS3E_k>cG=}c1;1u`JMjwAPU)HQk`e|S_b9q8+6Z|5v?c4jWXgU>|f zoUSiW9`AbrqK<=MQ=YaK_lRj+{erWYa+(p-pB&da<3SO_euUvR1S3_I98y5e0KoVX zsh-$dN~)G`3$-yG^>vr6hSRNnw-+Ejc}ljqzBQg~JwsMos(Vvo_UInw?`fIBU0S&O0B-*3!opU^(ynU z@hF$k3R)0#YuGx2e+*I>)?-TSSa!zg5zPorx-wQpF(q?P1Z2Z$m#s=+v$iJSTG51@ z<8k1vS^n@0vLjT8rpouc%l4j~lsW-Q-MB;aboo4}W^}wGX&C6LwjFeY^MowLIOaT-a$88b?_E>N&!hgJk%>F6uTYS zC9MMAyi)?{?mz>e`=-vjaQiV^NE~hqKCTU?U7t8C>Qs}i1|pfP`sFh4#I_YE+Bvt` zaq0WprX{1wztdkH!r=Hkbbbwnt+o_c$2#FlnTLZhzR%(+t97PGw`K#1IFa@PyeHlF zd9lWV`xvr@h}x|NX7iAt=4f(w{c`IEhx#ZcV zi}p0%HM3fCzl$?puLKLV1WGyyr<1}o5p+=D@rLUijhDxE=`7+xm&5ob zKAk1#0k@%zJmvN@kbbGo5k4uMuBPW-mg$p|zt4h64CYdHyd<7Gioc5;Idts0jx!Ir zi_EsA2daW`+{?fN>X8<(hjPbNWd8ivULzLpLM(P8)!+@bORaws4t7KM*vjHRLFroTsqsy$QQq!9~*3Zjuwq;179mFCn z?P$6G#22~rartoDJ^{>%e+8fbx`8>#K)Vp2oA6gL`&L_Ny(o0o`%Am3hwj|}{&)-Pp74X{piuD5yRP@;dN?81bD*JGdB)MfDEwXQSxoDWgz z#&9j2A6@jG(^nc|BqUt~A#9JgG4T*qY7naDTmSd+$bgU=(E>)JAw_Xh!?OoMenDc& z=Zen(#bgW6P-}5DA)}>ZisA>b!Wasth>q;;GSnADn6NNdk+AWPEwAH&5B zPKmYyW-uWN)9&|!y{&oz00j6no6h811jLH!%ZY$Q7{&K+0Xszadof(8gx|MD7S3ru z1x(=l-8_}~zr6hvfQ~0igV^6Z*q+R{ zt_;I(XF1Qr$sAZlf97$v>{)*LfT_th8E?xQ(cr^(YWjQ-@XLbmL1L72$hGH(^9F-g zYU%DQr=i%AaNUnMs`@^qU!1L61%26o&snjr`u}k?mljPsD4x zIl23`ZAw&%RKTMJ_{}~FK$&@Sq9y6dA3A}q63ajfl&HL95s|4ropixo!`)Th(_NOX z!H8$`UAZhMt}+IarETQ}-1>NuSXXoY>|O4C1(o>FUAnkyYV>T~_WfOXJL(siZ4>$H zrxtC>NAyqXFS=x&4c|MMi>nX@gZ1x>hk`B?=_g-^C{fF5Fvf(U(EH|j$@Gd7d_JT(0lXo^W?ac9rmKBQ%@Ce znxb6XCW=VSSV_qLxx!QWG=Xj1V(D326;Iob50WJ0l$DmX5XQj!r2`0pc3yp>Us?@tO)OPGDjOg=yHd*uIgESw@kRSAKzM!>mh+l^M zG{}?EC(E{Mf9->yHPDkh+RhxCz6*AcXeNA57Acm8GRf(#i2vXb&W+?M{-S3iNTFN_ zzcP+-2gj>IqF&h~?_LTiw|4e?@zkIxg7Lx3M~N-a^rPhqi70aF1G4i%Wi9;@K~0|h z#7KW`#`9$5)qY^bbJmdC2w!XZja)Eb=ezT{6;$U8*rRl2`-&7vdNFTI#?6bf=HIr- zNC0~Igt(LS1sBk-5$(NA3ZNz#h%=^0k{f7fh)#9Q^kEw zW72<^fqeHmo-RmcXDR=}FN|->U{LQ-&r!TDs}dVE3vf2r(>V<||VZ2T;1$n&YzYNX~dq zROwUm+}?0EOk88p2ZdYe{oR*X8f#4_Z?{=vHyB0vfj;1$CCw_x7SUlRAR~JdG(pWU z%~!g3&@wmo1+vjfkLiWo%(ZLkmK>P=AZfjCTwHSR0c9u+OD=s(k?iqEY{27wp0Dj* zYEkjnHFy3VGd)juIG;i4s=@;T%KaGHe;7Bf`dV~1h?RlFx>UMnX(wRLo6(sr~*a@vJOGh z5%6W@WBSoy|P=Xf0-Sqa*k{G#}JzbS%`kA z9|*1<-c!@}s|dykp2Dq!n&t#4=^J3om__E7=ouI>NJhC=NR(&6YOAPyI6;%2j9rw7 zc-^6jDz7M=9m?}gd;dh+xjn1Vy|P^eW^2EB*Vq-2wQjk3 zG*9nd+(DJCAIda}FRa`O7B@{>`x_d^6rhUhUkhhh#=BC~tjC*8en?Mymly3&AlhNgm*c)2ev3LV5R1D?{k5$|~*OemurE5TS=E3S&g> zj-af9XfPhnFPY)D&QknvK!}5VMBV9!u;1c-h^cY5D0s37^uCBL&Rp2Di>cge9ysio zD(r?Y*unWNW$9k|DVhLk|Lzr)jlhk!TlCaF?&f`R+KpKp7MW`9Z@4D5;OxsOTg>Bp zsS5qrL1Gz>vs#n~c1`mhK>hVoG)fI6NF*PRy-Oq)GZN92KyDH{@>|`0S@EPf+0lz{ zMDcj~)C&zTHs6(Z0b_A2$xCRVa;Yb8;9)y|Tu-gyW6%nj7I|UaeQ2p#%HXOIGYiuP zXkZJxlpBD_a={bT!#LLtAaIY1*z^A zAdOS%&N!QLIyej_jl@lv#Ses_NZj*5=#AGF#r=;mD8u{Om>n_4DpDN55kBrP4|Jr; zk4ft>12j}K0Ij`X2NY{=`#~zsv4HT53-c7_2Y`A_+%DKN9xg|!C%V$!1EtA*eZRl~ zD>8`w389+bDgYpIuqQ{s`0zclXhv)X=s@-{Tz7-^Nq&#qg-npZ89*P5&Ds8`tYx8` zf&T75kafR-9c~qaT}<;yPUM;jpYt{7gOq0deb{dlW_{^@(~{6f%K-f1Fi%gtDS23c zpkLZXJvx4iUG|=kKmvOozWL_?MSr8LwUg`xcX-CRwS}C=-D#n+pm0h>&a7)Ujh9#kX+Gf$0vy}V7VSHV7m1PrV!}YTr zTmK!D>s4xo>|{UvQqLyxQd!wcNR6ERJps)n1hKro{Z!U=>Y2`EDE|xX36nRf<5*tU zrQ|6SM$_Q`ivHA4tUb%aqoC;)f+d(Qp(dZchtKM%dAMz6iL{~O?BSiK@aV-`HW>r- ztposK)jS#uj_kHdv6Ia_C-aZN_X7Cz=+_pmYOZ(6v)|UNV}9v8w@@CoRl?A3pteHN zfJQn&teVwz8j3Dq-bjTjprOowQHgqGUlGKRQ=_?G?EKQF8^8U|SpM32&||xBbV+mA z1-~INJd`htYt=X@|NDGdqZ(>{`b8dc8(;P3>MvyViCsUiu`^WTd_JT;?wabeMXUsCsNd`?^Rh?39q|Ar+C{|0!wtugA z4j^^Q5n2zl#$)ZFomj>4$?Ugb$}jwWAN37`y_ovtiA8dKRP!4)xO@-ySCQtabsk7}T?>kzvo2_w_X`}g| z%xxsW^szVDVQj&t)^Zt4;5|Xuv;w0>Tl2d;2pDw3n=F>`p&Lng=%6)YW9Nz_Nvu+4 zZM>-xr7}WvAUvpU^)1j#js7wG#@t*BT`B?Z!HO6|B820n+Ge|)q<#VrajB)D6@#3Z`i*SBXdM2A8k5(fJQtSdu!f773?+ zf1Q@xO?6M*Ik2(bZSPjfRa<~3h8%RXKJnK`3FHTISI<>XWT6E( ziqDK}VuGJ?>X}2$gV=I^!JA$+lug8_AEPjW)4L5-!%%0`G6DQi?|=B&VH!LDxNa&HH&NDv!D&cwubS&YxbV6(LiqSXW;`a|I&qMq4Z}ox1!!YQUzG~ zsjpe*J@M;0{NsQ8YW96Kk5V7?92S3CG55WzW19@81r$7)x@8fI4aA`ZY?Juh`rMUm|&Yg@k3`Xxw<(0Ndz zb_LO%vBQq5iP)XZ7v8__1%4xXYGIaC%rj(Zr7_lZ`m<(qayD4^{(a3iXQ-va$(bvI z{&cyf0Tk#M5jsk~NdP;L7l~($2zxP-x5tknOa=l;#E*rs=RW}50R|2|Wd`0OfjZZ0 zzB`|@xKf|#mXw4Zp+^8-8K$j8bkXWvfN>ICv+l(r<`OaAuJNE`E~QryLAw5fpZ$Lw zof)z(kovF@3!6`$;4rcB%)u_1nzL8=R?>0m)M=yts?Hpio6(sxi1eOL*zGa809lg_ zAe#M0X0iRaUL!ET|8HUhGdhNUxI$aZ;>3VUYN=j?TuUR zAg$=SguNvAbpb!$WdG8oeq6yl@+ZHr2ZOm5Xx4&(4VZLH1D1m&gNmpif-|-o zbG^;Vcyzj#a8z}L?`fl2zT}11`?(h$@XWxYTj8`Qj1!9iDT`d^T1cI2d~z1ATDX4B z_Wl`_?c>jh`7`TZ6?QQ-J$OcEqRvwJheZr?EIyoh;Rvd6>*8CBRQAPHjUnB(;TO4O z9x^Ew!awD!Ess&78Z8cU8Op17bybHWJl7~xj9d@K4V-Wq(*@@Bz;&YnNb%c!JOwWq zHs5>=Wneh_*Xm0+3)!)h{s+Tzh`zWHLUG8uDf^^jrS`)E*W`wcl1n{2$^wQi;f6$x zX+yvG^elI#?)=omi9@yzM}a^rb%OQ5oh+e{1SHpuSryZ=Q?59rv-LB-I|J1|1MZ13 z_9?V+E>#1oZ}u7yKvHxg-#B|NcN(+ZBnw{1!_?5Tzjb}53X+4QQx`D*t?@V|8TOah z6NXljdv)%rezdOGj5`VK?@odGR_V`cYQAuY2>4OcNvV^0bzGXI_-!&}cNTB^Cy(jg zO3eI3E9#_5KR)vSyxqI4aH5I5Ho30QwI#8t8*$$M-Ol`jrunaB5tb8Ak-j-EYeZB* zFX6vfy+6^XY(tM#o!2ge?Vxe_ploll)j>Q(Dm-Wc>@uH_B^ocEeqm298`e#!5)!j| z^lLFKmNW!CHX}LE8d^d0@vO&S0%DuJyu^`3G1Kp|)xBIlh8v9CY#qRZEksjNhY z^L%ijt5I zG0=d(na9cN!QH+eFD|3PeZK}<8iG52qSL3}gj2%5V+uKvhiVq!)xfZQ{35oe|D;Aw zzWPtN)(tRGwt~+liJ`yeBcg3rZqHr?!mWMxUbha^qqzyaPe}^*(lXKNzr5Q7{sTBH z&cV*+>v^h0EWU#RDU2%!hv^1YA>uGK;nHO@?iq~C;taxZi}1#cwo+DOljP|OEof2= z@a&C)4@iD-6wA2TaIMAC7cDgs3JjeMXOEMwNjB#;BSKFkEPm1lvjx~fPh&0fV`Job zKS73p0`gt(enS3T8&MwVRInS|5k!{2yoYHsyUqg)ICa3o_ zvu}4>pazY~n`^Pa)v*Fo0RRba*o93bE7)B*AW`8O7t!-`OMR3!mx!s53ux~-=N{6Q z9HQ~G#)TOBq?S14_sn@#N?uf9KX{ZnW7b<_5Q_m zfRlW^x_{7{q(c@H$>sGF;fpYx)Lr7)-y7VPe~ZDn4G6pb;P+RUGBvan!|h`6`S84c zQ8JI!e5GZ~679n2_97Y~Ne%en{;_6o=+o&lobz!?b9J)t`w#El=v|zC!_(yl@QZso zX3ds*5Pa<<-$5l3V5}wbtLeq{6eaaT8}>`2LI3%Rpy*~GfoCyX`0Jm1yR`^fEIBI2 z()!rs-5B?<7JJN4nB_V!-jCp{p)P6p5bwL!lt1A+C5NlL87sIrN=?O| zBAQ1VThI|E4HSdLQzA;UF16e>m0Ezm4m=8fWn_sZ&r32H4@|%8XzZ0IRGqd3(WADZb9h zJ;_k#vOnntA8#H&24RXTH*xnhSVP}wMvzk}GE{4_<;TC|jP^RK$-u8=EDBi=?b4o0 zvd(W-eE1{8Ou8G~9sXobp!atr?sOmSF8}ZJJFY8B+3G!94m4soTa4DO1%%oifOa8iY6^9CZ>k)~|2-?2ZC87uYnD_}8rlCG2z+db@Lu~!pXW$#0x)hV}@(A zpU-}NRH|h=J6#yU^Td}+e7s9fc-4~lj;m=Y<&;BH~@V4h|Zk(o>dJD^HRwgpI%sfV%6j>LZqi_)E!JeTSwo9(`D z$$GR4v-c=;H5#7DxwF7?RqO_X9Mbm0ZaHBts1pTT^y}aA)Ii!cA(ev7{A+Klu$_rRjkQR|{?7gs+&ke+=@k`)LyxpwX54VP%IF z8887lyr+fm5-I^+1zjPMGr1bPiNk_&(!xN*cUkMSm}R=j7{)n~$EAE-C|18cY(`bd#r-#6jGp{Z|$XI&SJY5txi92ck%O8L)-{2B` z#8zXu^Uriy5PuzC)#b>ylP%zm+-osfv?K+-@RNC>l9got{0iP2kQMq|OZ6PHqkRCr z&umf-MeqM$0xbHx(kmAZjdAed_mHC4W-iA9^0H~>Eshz5nKCDs?#b|j5vyh!eps&$ z0GNMG28Qz!gW;Vt59~vtOWy7AekNMUGuL9^V-BgJiM)Fx0cbyaofmpF|K5=HZhbz_ zC8MjDE>6kX!Xki5-X}e>6_BVephS9TQ+tY+-uakP3pPKWFJg&ap-;CJL`mxjc@10HEYr=P40 z8?i<60dft88r+0U`?`0U0uEcYck>h)AF-h7O%x_NOE1f;E1&;-MB-6!Sex?i#pzDi zgdz0j$f*IEC<3J8wargYMP-ph61-mxDW5UFYxRN$KiVYz@;2A?4ud8bH;qk{P0Pac z)1F)DRKSEZa9vCc@pU7aYC`-Cz8H<#v6vZG|7u9@UUgAi$oa3Y<4i8O%QaYHVW)8@ zk%lUU*lsjRe}2gwbTfON~2#*j=g2biP2>W?+{m3iymO zF}0%&{D3E^;WFE$XW>r>#xZ;yANwMpg=Mv}xb_C9j{8({>~@SPYiM}ALR{C7f<|_F z78G}U0x{G83~eR(1*F}tw>AdVv<6}=TC+(9n5$Ig7;6H4q9;0_3CylhpzV&&k2VN< z|6n4GpJm~4YIVx_@I8{Tgr$(c_BNpUdv?58h{!9Ted03uimC$s@?%!N-oTmXym7I2 zBSW8B=_&v;8*pLc?-oXDeC$(Gl|D94xlb*f{k^TE(oXFY-rJ54s8)t*-4XNKuZz%- zDsMaq&7Z}%{RA%}VC?H9J>hbjlrHoq1w$D0g7b%764wzN&jre+@KEnKwn6IHsIlPo z*89Y>C$g=YUZL18Z}dkYa~bqc!=`mzAOg^4*V9(aD>3xdTys&!`VzL>`RvAseePpO z@)fkkKL$u>vtZ3GxC-7b^?FG<&eLhspHyErb~`StZ+7yIXKJ9|(8`?+AGy@HUDTbi zNWVWkMp8JL86fpoDDhK=SGRt>KYYrCrpI#~cxLYrw14`*SCRB62vETOGHgCu99*=d zg^jPK1YihbcGJ@lt&>h!!XNK4)sE^Pw9PPRl&(rZbp%-^xf}K?fPo7uMPqrwM}uz$ z1jPX`LJb%l+VUwpW^1xokL{h`naoM&kZ^QguMry+k)We%LWS0Je}x6k;Np&7;Y|iB0Xf3rZ*M>-|KwmHsTu^cZ5HI+jZCc6Tzty*<8`Xa z;-<8S9S7*=`!c zj@FRV^%l}vv^v4&3veZ2+(s*Pq*x<;rcP83%j0`AIdW#FA^}{dk8JTFKzi2aYFOMT zIjXn{VjBhC--(I)^U7H~WgQ}yh-d?585KN0=eo6RdREOezmKxDL_TPBh3J1tR4JOd zO^7Hd$N$Qnt~skyRrloR7NT02FCLc0+@G4_Ud*`{Bw|^|xEc%de`c@4&gTfx|0evL z2K$7#3IBAk;n5Jcs&L_(ApcT{alnmd#Y=f{o{{d~GnHf5tfIp)c3V|Zl? z>XuuzTFgf2$z(;xg!iJ8$}Q#8)gke5-(BV6e8N!&`~DArJi=7ty*Q2f#}Hsly=X~n zpMX2lx=o7(SL&|7^QQhW)VrIAA9bh7*Vb;8G$i`WjNXm(zYqxccG@5PJmTN|MuMc= zGqap2i%&SP5BjAWJ|BC{DRKJRBS5!=od!k5cVM+zfyK=~1g1}>rhi#AW^_*LvOCTS z`z_y9y9pjmQ`57l3Jb5y2Vy{t8O*vh=@+o#AlJb!KuOF?-s}*M4BorhE?KWqbmJw(@zS4_ zeq8pudbvVFVi6i4XOeBvFBzT#nqxYl#tW53p)5@&N_7lt^ysBT#evt?tr9r?c#~^R zK`?snDa8#;FajmmMkOS=hGPRQ_YHYE6Z!ObxrXzseE&xh-Y+GiJe$qDMd-4#VP6s< z2CxBDu2bN(SE9?=;US6!gDQW5lE$=+0hftHz&G`@zmwfq7+R?@9qSWX%(byv?fn5& zGz~d@Vl2vTdY9dbB7NZch{A5*y$qU;ZJ?GBu_+Y&eWFH?~{M7ZStFxl-xKxb037Z1sW31!Hgc)Ahqx}UbYI>SQ~B8;LT`2 zSwM{Y9lC&40lQK84WDY27Bi&E&%5bgbku5IvjW&5C&f<0RMni)V}=OGj1YQ&2k!a0 zgpnZYI2+&7Q0j74jq?It3&H-i$8)I>hO#<=%$OCku9k+?+6CBpjz>T3%B~BoV2eCr z6P4n1r4dcp&Tnztq~T~vap=;Cx_0`qv^(pXrcV&tP?Pala{Kn9DM?PftI1z_x2A23 zE6Uu$*?#C^wj4<(UG5vXEaObo4$mCN)~_yWmxOj@S`-_iY)Cyj04d~rCb6g;8)HPY z1}JeIx(VkXDxFF`XL3`b)S4m)#sXTfWZ2+*t<@V~lymyxbVq1o3w>~Z^O)&nLwq^R z>^MfiJQ?yXkj^lkZhYiR90_^X3edyff!%o1Gbwg%EIx5RQ7wPL%IdUS{ga%77{Y$O z>Xv$CoVVc@px#xhq~cKG9}5ZxuZ>n61pYymXVtv7szva}R_feJ3wZIdjqm`yUIg?n zJsI0E2$h+LB}RC?J=7w^hXp{ggvye~eDy z+H{5MlV@6#Y&8iX=`KduB z1OD&#c9N9-vl!p!@qw=CHnaT@4F7R3MthFV2ky|!xeJ&Y+RyMy^2t4`T`-$i-?sgN z@-kKO59eq}nD55K=5mclRwLP_<{=8L#jl-TT|2Ni z>)u(VXnpy}9LE-p?OqGaTC^kAF&*zs*LC1BKET}pWOhzctk%E$`Sb7{C8mznVYWyOcV7pR7gPqL9MK{}_tMmEC+{O)acrq-TL2X{sIea5&hYsPYy zvqD$lC`{xnh1%F`uVqa2&=e0IB3}BPC$rpb%|Iy&AptB$inMy zrPaZdhq!0YZk2Ssc%8y8Sd7@#cE2>5r#j*#Yp_>4T|{@~7dH)fp*Qt?lro>Z38@4F zN&KP$?Ps+?n7xL71o!=)4L`@^S270el+#5S*Kb^Nc{yNxBn7!cH9_EE3KPQgqw%7H z*AP?KFU{)>)wH6hmEVe}mN8c!jR&B~)IednC48xyuje=g{8ds9LG@^ z>PkpeSz*lkg5yt^I|7Iu$L}X_K6NS4?}e=3y^=kQM+@t=4ef`zjzF2AP(*`Xj~1U< zaX#rWS>cB}kT$D@gkGCd-uvd0d3iYU)T)F&5-NvCXq-vzEhq9$&*Ad{ zp3hxrX#rs1!oF#tB3jpHjk%-{=nVup4$a?Z`}wa?uG1!kTS7S3zNjLPh%jH(;@{#m zpws>Tm4+GR-g#qiN1Cbo7oegt?-!gw`5-HX5m;MVUUj^k+dl@sKHp5f;!f6JP?X!S zBfNy(8Co60vi7VGl^-CWsSiw6yx3!!1!(Ug2>IlwMAPLjKo*kD!L*$y{Ifp(7$86i zDK|TC+IzCm#B$Y$&LXYkm{L611v{}}BkezL zH_ERHgxJD`{hn8tr|Gr(8D#2-keYzKTzd`vuT^Gnk%a@!wl#Tg+kvk+VsuJxzf$Qq z`Ax6-S#sdE1FAUu+Sn0f`fy>ET8KCWX%=YUf%S|+^+-K#qeG~oTs4jh9`QcV8#X-Q4+}e%OTXD} zz?>8{I-PIO>@XOjRx~=D1O9N-P$rF2oJlBnSMVJ1qbOXJ98(f3>#6T4f=5j*nj7$F zrKp5}L#}gagv9{_nnzj(t#Y%2{J!-4xockW>3=W4^$(CtHC`an#pXrS%nDLb{D*2Vs>R|P9kR9Qblw4zx!o*(PzvVtg`5X zL8&%W=RbjZ!X8+CL`_A#;8*OAjYj!odN23n4n~QTQn5}eEazPCN|Zu(84BuHTyK8z zF=9LNVoITdhO~4qNsbBA+M(BC8?*KsUaQ?u3<08}Z580L2eor2UN*cbcD+59QU4_4 z{s_c`Xj|$pjGX}21jZ}OcP56US+U&Hfd92UnKmBTlgEb*?PFKL^IV5h&l-G~Gfu2l zf|a+h-Q%Wkce-l>{ZB5d9eRpwapul6?Dz3!suOq-!WCT9ZYn=`;Fv{;Uyj;AQEmjE zdxN@}z7eql@7G2r1tdy5%_SN3B4z00^2=Y0r}{8!|EmP8K$hZVA&{vUdPf;iZ&z5DpB*Ej`F;}S@&raSp9K$7 z54m<6E|C+t(2-^xFv*c=hmnQA^q$|%*N#-#ZtY#Fs%pkg?U53DOWG=0vnXn&s;XwH#3nUEmDG$;d(}>i2pRpI z_vic1?_bH|oH*ya&g*(!*K>rPolGJWQi}C4!#h#;;s4l(H58Z%Bd^APSJ~pEJsd`e zY^bp>q;kyLY!MXd#I48R>0UnKPw%}hwqzA}m-##3-;IQQ@HSi5BK6mEjnFVZYPl6x$q`n_^V;-Gv7&|NQ9M6esTR z;QYUHEMspEE+LPJ5NGT?6QF8)bPQzUUc68&nAlqo&Qn=?ww}oRC}mapdxTh$K4V*P2PYgepL+nvIC{$Gr%rFS#^2H%4Jdq-bPY@)(e6hI zH(x3g9r@f?sBG=CEGs5ILj%UdC-FT9VIY%nNv6##toXq9lWfBv=++L~ect--I)_jKkpyr8$1nXYLX3CDR|rUxD9YpiSHc)4kt}f>eTxi3b*E>GmGLUaI~n zdvW3mg#PG%4<&a%9~wB`I^^78(b7P0^^10q&AhNUF#5gv=hXP-kEuuh_X{jOcFo*t zzT;{m(8z7IPXmwt`kz>aoUuJY1};*9w%N1@U_)rK90M{njX>3v=4*s-5Zc_JY~?_uSobsi`Lkn0C$=tK6ue~l6ls@0S#qPw z{$)a7j^W#!iyPPJKz-raM_&Fp{Os{|gitO(;;?1AxyAneci1|(%71Y+Vmy5p$Uu8l zvWpvLJfo_Swa3+v9ZC%CK$Kjx^5IdA%xasW!`!U~JPF`v{W6YLql#{Plc#YZmuawq zrV%`W%k?jl^a=F8#&iy@@2d1!3Yf@c2{4;lEgBBcbO{L_K;4M#{L7>o3i=x7M6cIo z!tEA>h~dT(@IWQ_!C)0J1Led{kDD-_XO>VeSD=8s?z>s+43Ofrg`{6D10biV>=f7s z{W=euXdwwy2t{StR06%_G_Pyngb_cO_g<~E%AwYw+lL_?TNOgC;Ki*E2Hh~1i#xHf z_}TyrS9i(f+uO6676}X+hpLzj%Rnt&jvorPg4Y@U3j&QoD_41Y-9n7=13rCse+}6Q z_RbH$LpGpKksZRag7PymT_@C!(+B@kj-WH#YQ27>Q3#VLqCty(BDsZlf-{1(&mZpH z^j}M_zlx?nSAPC6IvxXPPM|>$8giERh$0T)Iw>gSCkIIMad3Det>U&vd>{y+h09YvV)L=D z{Cr533CoomGw4C+aQ*xEZKK2L!aEc%N0k2>=0UZ5(=Dl8%k+vzp~75G6U@9 zr)ld!{ilQtNg5y0IDKyk{_0^ha>?=*V3>+InQIq){{vxu0%=R%dQsv#U$(sLnk7*} z&8g|ZF&7>kuG6m8bJQWG8E5UIXL2SPytSYWsBXui!0(mh;EUy#9MblvKt|yUXssnG zQCk+A*lM?QktV(3V(H+YbTVf)-|%pE100KMAjHKFKfr zUt~D?6SK*-B);B%z8II{U|yg9Y@)wxLXO#BUe5e)TV_+u^#1wx#wi37#Y$1Dgfhl- zMFgYxc$L^1gU>eyE8w^}nf8quNp;c<;Mm}K%q|)hN(6u3|D$l*QDg!m;_(D|+s9@X zF=+u8t>DXI(m89T0(-2|_Re8%{BRzFj`Uhz@zBR?l-(SqVe#f2t)^5y?~O&-d$z>6 zn#Fm6jZ;k)m9xdO*|~!(-$UMX_Ce?+=PtP}K+-xED_*Eh=%WD@jH^Q=WE99GXK9ZS z(k+uH7M9@`xZ1n^tXyx|E2&Xq#~O7dC|Yx7>2cHL+zRqV49m!jh<1(md0f4M-Dv*1 zS&fzrBn7#(&jR_@mLlE(;;8n>G)#r-W*&#qu3|gWJyC)ZY1yJynPA2bnKkfb^i<}* z_K}1sDA8C}E)p%`eVkNTPuwu8227u=gQ~SRi>);a<8^r}H(jLA%79De&SHNNg&OFe z^lG%4WAp|@U=espkRvX9@GY6~4{m(B;+Jy>$ZSr}l5dYVjYL7q!&xxSqn~aZ-B<}Q z4o8#*)cdt&D1P$lzd^*T8gNQEZ_d;q&EqhPVtu0u6k|H2bipUzFY3`RVuYgs?GL@Q z)zsx9&1HgD|3Hp?Wa;MCa75wwk0@T?F(t?MLNCuuRZj{%d955@k=*rR#}esnCv}7V zG3s9f5>%e?5~J{OP9+d2zZsLq;L3*r@4K6Y$z_|+8E{Q~-Tn?6z5e;FZQX}>dO?;l zy^ta41I_NM$FJXfRKJa_LDT{Lo`x&Hy5s?EQ+NV=!_rQXr;ieOV@ z^aBn0nu6ROQmN6iz;A$3Epgls7%w^NxSfcr|7B`h)DZ&)Y{HO)XM#up??>~}iDk$` zamY4YKj-pt?_4Ib_emA{HRi%HL)R53PO3S&+i$u_+?j+{MLe+|HW(a|3l==kO{8aP zJE*pl!KNeoMr_*i_xTNfWNqXlR1OfumCCuNwE13{Nu-ky289#s+?#DN%Fw1Jki?Ph z!I|zE{_Nj{3B01x>bYfdX>=1r9eDDO6@;vP?rHAiWJ9*Eroui7Q zf%_v@g3UY9Q5=~p-OjF%bjW=vjQpP7I=T=DyrBuhGoR(f8Npi&u~AS5s>& z*gSrpY9*I%xyyYyyee_FC=)iKQPTA2(cs>Oou-UZ*gdPmSr8D6bKSF7f4D*Am#1nY zF{G@QO&NK5rCgz`VG!XVCcW#dX?`=_AG8cv9c_0uq)GLcD*1skO%#459lfyhQ#!Cr zlohCcf1Vi?F+SXS`&co0Bp_@Fz@KMmvg!NxXN7$JGKG9Av$=mZGYQ2U#?o#TtP_|I zDe^M)I=xxHmH6WF(5GrxJ5jPzOWoekFE8`o6Ysrl&W(s zU**pti5t4RaHJ{qL-p5zl?IPk{BdN<(dQFUr?PXh$!%fPUC!ENpdBkh_k&~aUupPL zMWk(CiaaWJn({hNr7zyzuJowI;5>@<{cj74$FOB9O3~|;4r_<7sLL_4Sycv1!$Al*{y=sO^uS|CzpSO4w)l}WJF!&+6 zmweE?rgd#pHTqvMq?xo-MGL2y6-4(7aV>KZ%NiCUq@&6I(K^k{K-$PKWrdngDm;o9 z=stA~Oj!FM2pK{N zs|SBI!6hnSl4>Te@J&qu+)xU^kf@!!JP}hKb!*aP$l&Bqw5RY5pwNc|88XjHMsnBNky2ojkcaqJ>;L77M)lY%~I^iK^vNX}Z zfnMHv+4}tcQKJxus0lo|=dFnvCNuYNBhoZP%FH z3*XVZ@$FHEDQBn>*ROxJ9B@6z$vxcs*}4`jJa?Ff#jsECC3>OJ`})dPPnWOdiyAOr zXiuTP%{HJ&lGeKzl4F&ODOmCB8&{L14t@Iz3nD{>x!uD3^V)TVA zs_(H?x`0}A;e)I}mo)pDx#Bf-nHQVhB=ya@8s$HoC}p>n9e`ui-g2lM`!JwXs>!A* zJCIa$m?I_@RX=NP>#1aPjXo3U?}(G^nk>aS2|ryS*_}#u^p~cE%<#(o`llalx?g3d zF(-4c=NV1RZ=>Lo)#vO*mR$R^`4mk;izAH#JNoRn-_8H(i-JK;(~}7i{L7UZ6y3&B zglgseNwgPg^XyojB8jDO)z6cwe9X2i#$87a2f6?I#_xR9NUI;qg^rcxVzSP&-n`^hDzejolZA`>ZzHD<(#m@ey z@@%V7T)R~L?zD-Y{&JsqRWu7#fHACjyu(TL_7ZGw^A~Oaxi_XLC!aAm!xnz0oOvBD zsd5nh$-kjW?dEoqNVWqO|C7LBmKap*v7@n!HiFVxQ-2v2bz7@YfKBZ@*QhLnTt(^v zwN6(yosyu9qxH_{E->ZR7!~WiCvs_l-3q$lXmSBMGj>Qf`M6{Rm;)lyfF|h0MNDc> zJ@Pt9G5C~lDCTT1Mff9gvOsw}Npef2hnlQIf9=Gp!VYK zu(0qVVS}95^@4(BAz|M56Mxt5l^$R6HxE#!}C`gEq!W-zrnC@46fPt z0igedU_bHcY_(lvAGjbWp!dmYdh?ysj^L(KKHy3lPzdNS*do4*&SBEVz>h}VFM4w% z6zQ3+g1Vqs@mBGQFzrL^5l=4wVU?Z*0a;C&lBwECONr`7c(!RT4+t;U)grko3!0j= z;TqwqpFEP*xse?Xd;{aUf-`ZQ9gAOp(5*BEk0kBt%d;1f0Z+Q%_%1nS(RL3CWT=GS zEi@%H@(8QSDD|ae4x(ua>uSil(s@DXQ*?f$*-$+XLF%v!5;K`OA@8tx`WCCO3wUOq7IH|&vCX?j}8QA1nY`qnQbo( z7Qwwy(K5L%qBy@hQ^q*Bl(Mk0{P{w}sCMA8tQy&_A+Jl9rktI^;DqgpXZhu zA{<{u*KdQqHf8Ri*5=}_+m{xZRh@NR3-9MtO%>rb;^e}=b-W^MB|t+fY{bn`01mY-NJC(~M2uj_pWc9he2 zvKmFLER4fwTqX62AtR^K_H}a0Kh%EPKx+ z7iI!0#OrRHMCJ0H54x15v1#7FY1#3sRPx83ENvDLe*s*eDfD9UP%0_I07h}Uk8ueo z{%phjZGGk%WOz=D0$xP%gk`N;wT?LD?(dr@>U+6%_%a($?rhkigpQ*57Ta1iac{rb z+f|%@b9rQne`^L^ghl~W93P#B`*df_=G^AcJqcS4t0AIx+<1$ms~GQzGJdXc4hzWd z4?sW1ECxt#4<@KbyT;n1@|o3DC0PZ6nCg1le2)a0Y48G;!+V~?B}J%0x!o=m^VaI_ zzvf9E{9oF+D9zB=_M0)*3AfhMC)HUb?iT#8I6MV9C7d4}0(&&$Fuvz|GP|Ewpov80 zpPJ~U3$QN~BVsh-Mi|tB8eCV?+o6m1%UAZuPn#q!5Gth1OYa`3BKa!5c?{xa2t8jG z=V~ZX>7fR1qAV!yzs=hlzpYZL%@qB#)*9IDs8o0wCF5fT`vnFDLa%bMomIg_t>!oD zy6J_Bh?NBw@Lfek_OO=L^w}Wo+#}-e^q22c{u}N3!CqEnQjJ~6yQ+fkW;Y5YZ3Lu_ z!}@)cj~Ej>#}x$N6F+4nr`$WBN;g(~3RbYk#)vUCz0bo0&Y8yX2vawxSn zn~c}h*JBNAh)HrC$G?HCMmhhQ(p%FC90ju6p&~&Wa*XR+>eNbS9VNi)aH8EkzYSem z3XabrpA>J^aL)-?RT(X>KV%rImBKB{)=*byhSAGHYt1dWHfuUIsXFR3^)lTHVOnM+ z=G01wT1>j2JbJ(6^L1~oOFpbZN{Wzgo*NZPGB1*ge*74J@9fry} zmK*FTvy<-Gto`JV=Iv|J(=*ZQyP>*@;fHisd$N~>-ky>iMF z3@bfhQr*@bal%e7UQ0Mw>iz1J=4$-stW@6({SOSxs^)P#xNb>$AoovQnVn-Ak7cfb zI#aNVBjytgJfeHWOJQ?P`i(C};{sJjM&|)TQe3=IT|3%@XHUP*Z%oW^b35I^A^QmN z`ULJ`&iAIw!B(Ngr!8~-$gO2N48L=8F+2!08QH;Gt3PZgS`x5Xc_*Z{PY>64jiEw% zTw40xS181eh^__vf4RI-d>Ams+gv$O)QaEy^$sD08zBOC`crKw=Kg_FRBgGrPpmU% zO7wZlT6|6&=5Rjt|49!Wk_}}erfwo-3Y|V%?>2#?__ypJS@gkn}{W)BQEyRl<8eFIE-xOp#WFZCp0yOeTYa`wrrj`Tzx zu^pzvO4g~O;vRXRP5<-fR4kL#_1u>VI#B+Jjofem#nCubKW&C&;_U&cI(rn`n2OyI zFIiqvCu9*e86`wjH@=vHw{5=zLBL6Yx2K_2L29u4~EGD>-l79Oa_DG{jSt8|YUBjaRA z<55Ujh=iL^{Q0lpB49kX!tcO|VuJ%+rygw)%>2WIgr>zMh0A6)`JRTsjtsv73)&dVN zd_x=0s>1^-{xNO%fgkFxYVVh+2*kV|yzRmg2YQ%ePzcZp=MFz^o@YV*Xn%gRYsnV3 zoG?X6W38_h06g?q=rG0mCxHpmlq6#ukd+jP&~@#PX@ z;fHDUyYVIB70)`TZBjz^FBUs#ji(lhrJz~(x|Mix_Np)aR+t)l)yc1mpNOO;gGJL` zzxk1>exd6-;8^ARZOG~JwLhi;|BShixSwVMdXbU*ACPOQc^K6zmdA*9-p>PiuBT>~ z@TjtYBN8;8)B2J;5-|K5J@?MpsJJWT6XJP_PS4(mkLL+F|Ghkmc#?j}s-!JZou}^l zTyKCE=lVH|;qGq#k*b-EK5S%e%O$^_>E>d+BZYUpo2nx!ZKXeut46%%d(1{6Y)Y7p_G`XL|SDlDfbW=>v%bmoppa>20m?nO>#I8 zHO9zXCvBQNoDWMlGE$I8UNjPN_d&1v!Yf2@C*!8ETC?JXt)(z7Fj(w#nkZbP-8Pe$EeKjfF@g(5B#YuY`jbyK)0o{9Zt;dW^2>Jg$xRPwQuYV152T8>CdAK zR}ekWx`zkU0*Rj5tpj`3lf2G$v4d7GE?>qm<0VX+M`o!4>gxs|zwY&JbNUz(s6thv zWvMr!EPV`?(Xq?T?phd_AIq}vCaU`6^qXjfKU$;t8jbL-v(>pf_4<|&= zx`n3B{(jc*M(AAVrHdVFt*65;e>!K>t{`*eGwBYW>eiqc+Dq#lTQIl~PGS|vOJW6W zS&vZsR~u)P=WHANT52f}k&-Bz)^En&3=dL5BN%tyl@1EEPFMxq(=b3zbMEo0F5o=sArPc_l^kf(!=7BeE64UFfIj_&M@I1V_c9{^@ zevQUUG1E3)@(DC1WyMup^*-e$n|56l|Mr1XGpX!S*E?3djurP-$;HrQcRIj1TKK@L zDT)eKKE0joZ?~Gwu7de}ixekXe)Hau?P}NPtB+ewvI6(jibFy$qgD>oU}GiQ^fCcy z>%1RwGbO>%xuHmuk#bbc5*wHEh(7jqVp`o1&!If+YL*7aj_F4wBsZUf301`r}mSkGhM7rqSpqX<40M4&3PlR~NECT4CvMV9R^+q;0T>jJZ8 z0aNeah&`iLcxiv?7F6WFk`)JBNi<+#a4zZ_*es9W9 z)`6@=Rgtbk!4MRvM+}IQBwo^WZ-LY26_5pnOXCOfb^^VD5M3d=U4jpUje#-Pa)8v} zF-qGe6q!DJH|hd#c5Q8qi>Fb8wt(KmXbb$6cAL`g-*7H0Ob+o8Nh}8uts>!SzI;-8MjA7^8>nM`$dY4!YH)Id?a*n@q@zwIaQpn)FJB!q#ji3b+2aF!?1|R#)?xrmrY_L z|5z`eNB1m|ZwKryfP^=g%Yw;ejcy0a|u6x#Y?-Hl6ph*T&Ty1X1dk2@aQv1SZZ6@5ely2X;{AU(IRFN}7cofJy z>=(#p$Yk7YG%U(2&eXhu)I5cdqv<6yl`@Jg-oWcRW~@Gw^Sqdwc1Fq_-OPQHBrBOb zDfvp9)%w&ku5hfk;dgfWLgbxOVZjB0W$ws{dy0N?W{ec`Igs~ykJ};1;>4|4C#sYW za@Ks>d^4I(GWvcB?U849@QO&%b!)@v3oAdP=5}% z?tXmEm+5}gNsuX2b(6t4)@rwWG`j7x(%9Oh{$MP6`x5Gz-(%xw4HD_tadMpkFv$rD z#4TeVnJ&hiv8qX2uxM6P6J$?J=&K$Ya=Rx|kkyLdc05T`+UA(>{}wxK*Ant@{Tf^u zIu%D4Nd7RP?Kv-_Vv;gDhZ#|v*sgVEJOXCH%F^VTwE8HwNa=_W%Y{>@BqFwemGI>;KeeTPAv8H|UBPWRsKx_>F2mv5B0kTSlgdC! z3L&~D6`j<+qG9^V{9WC~aq%tzcM42pQmVw@P zFaYu#e5!Yr8)KU;&ZgGz#D^0rx|;K6CWanZA9d$|s$sPpuVdBs>jIW;{U~l50zI4% zZ)z|@*w(0)aY`TwBCs)ZNMxug_tl18W6STY{x2w-39$J{PJxnY0d$^6by=xKaO=?}^r* zF&+)APAsYAd4@X7xhN2z)BMko&Q>f5(xU_Gg6!pBIi%*AMOOCOQk!&` zMG0PZXj@mr{GLzT@OM16gtK}H=uwqCDlVwNVa|ujNGC-A3EHCpt$HbtJ=ST;^FVYt z&~D7SB_j)wI@HmD!EhvBLdWiPlU0)XJ!8(-&LNJn5*c<4X0sZ=J#Z z(Mhe|T|-|GeRte(>31(R8y(TenWK8V$+FFPZ`Je+ zT;+TvSZ*1z2#yU`UTQ`~%U>U_lL4mZTb8j+>pYH0Qxx#*V6e60B{I8Gmc-mx=_MV%TN(m?hl>0akeDFWzj7z zpbVL%CAkrC>nEtEKw}vkw1+|9uyxJ==l));`f2nh!jD4s2B+l*;01f+cjIVaByetq zO>MiDdhb@3FOgpBLSX13d)v*4+xj4(yM3j}xQ+eXnX@uW<>)}aST3^d5vKx_Ch zd5YLK&oW|m57c8Hpelgtu2bC+#~GMbbeFEjhpU{+2SvNPyZ;{DHtb((cj0{ZFuczDz>~fQ4laRj75y3g zDK54es*U_EqLhnaj(o~so9kVEeu|2N(N+#>`?PvrqHR1QHB)rn`2g| zg&)#3HJzKN+n=~n3Ix>;@CIa+b>u~D7mlv8OYjSn9~0#H{|L6X;42B*vtFTBwD><; zg2T$(FEt5erfT$r%XdJ9H&N$k!7kOFgmjzDh`_x#H>RDwYcDVBox6HbM-N?(0Ra%~ zEPz^)+2PvZ!gI`|7kWaQyaPAVOi~mdmYIM5v%s0}tFqv{EUn@u2f6haZ@hfd$7kk0 zx>fgvnUuu4;^68*-RwU{9!krolv8LztL%mBWsanKy`qAn0yh#LjMjPWpj8yH!8g*D zpA@vayQ>c=dY5hoFD66C#q^rbq_t8Qx2A7~`WSl3ug31&-FnjH0@YimViKiw^gOHw zmL1BrN{*~iPZUp)0LB%GGjgq?OF?-9ub#0islFw5a*;@+#39}W)r^x`MX z=Th_JKIE@t-8K-uEK|t2o>&~4*jg9hziMg{DI?RcF=HpT-`HU z$nE37QpMxfh7V_j4akYvF?i>_7VmOjd-{kWp6Bp*yN4}=F1NA4KXUf&_KKo z!Fj)-r`{ep;0mCqOB=Ll^a!>P^=bvhJGHZ}Bzb`TW80NzaS8#zaoPW4@F96iKOxNz zAPlx_0r+bKm+wGHKVX{$JHUaIRKpL^zks2dKTtX+F3Ov1|KGGN;sn{M6#;1ju1(`8 zFxLZ#FpkW}T#XJ6*Hy@P+Eq~w$t8nCcN{H};=WP4@q^HN$Bs7eqF?2hgLYMSfNI`d zs9hHWgU*Jzhxsi1KKrP9`7AirD^JVGW8*Yuc%m}eBst2;WX2|X3%V$hTCg<0Bd%3y zvi_JfA1hZkXuCAG#B!~%Ay7E2ufi+a=r0dv)w-Z;G?T@OioQw=miPW8Rfe;IzW-WO z$@6P2e!|Df_?f_kxYDKh)ZwtNQ}p64KC8FkYH457)m;Bo%@0+Q@|H`eJ{ z!k`VuNUDZ`KbjU!+$LOdw85ye(1amh!pzB|d}EC?bEESY60H!$B&Ic7GPz8gksMlUy#T?M&M=2WG!n{K14X6KAoh?i$-C)aZ`vtWPx2+DX}DX()-N1C;Z!g2XYa(9w+^P6Tg3)hd%SAlU6B+dM;>Isc%vq(ZCbv_n;PFfxEBTreG zj_{FuV)uI7)$+W9u$!xSmz3x$Wd1k@-v;MKZtAH_U41sIL_-Mw?f9BwGgefvikZ!1 zz0Bv@x@cslYFfh}y&zyXX5KZ%4-_MgqVQN0pcKXhL##CCr-aPmm!nKZ=kBK%MZP%~ za63UDH1O-eZ&i&`!fbtn^lX>p`|_nH_b&PAZ9%zdQp7HsP2TMoSj8ERBA#Px{O$2N ziUan|SqRSmypcuHF!{HnL7`GoGwiq!M%4Nq7-q6`X{PwZ$wr)6#K7BHTXf<$2`3aP z+SU`{Y8vh+=cpcZ17W$|-0(Vmd7)sL1d@EXs{4#JvGbUR5o{prn{dI&9=49o5J z7!M*-XIvg3E__3X+sVKhWb4*1hMlt3EE~hNZBx=)GNUHnGCtPoN^W93NGjd-!qWa5 z`w0Ua0)Ym@49`D5Jmvs|zQU zwaadr&Lpb^`W(nwq(;Cy!?R#IE{rx7bsEfi)(Km^e!I!hm4IfXM;$C9W2{0>UuD?r zTDYKYzrZ~{Ij%;4S#dDAdC5y{$r0Jft}uVe?D@29@Q_Tb<_cVf*L;mD$-TXlBcXiJ z9gnZE)|4(8VF%rP@X64Fm0OgLna~z2X>OGox|nAF$u=peNl|q!K-%+&GqpX`|LuL_ z2R|Nf2d#XlO!+vn9E6pjHLX>#92++1H0fgSQ_yEn1(ToSPaoR^%o;ykg6*)saeaV; z`nGvhl(`R6PAubObh3Y*Z}2Z1+j?Z|aSi|D6W4#v#)gXHKVL4%0{Q0+8&AUXoVVsa zH0C)uw6f;#|IWWPv@69k7+}!kkqUQ=9MkM=DW!;a@!8Hbg^Qv-O+9zZd7+`h#1zn- ze~H7k7r-6t@{7quk!8HFpKfC8Nr#&T6iD}c9eU?%d6W+coUPM^bho)GyJY_Qp!YEV z>ZfA954E-!U{6@a3{SGLUdZV!Ysze-YM#rQmoC4R(CzVk0{@@=LRwO+Fh}5E*i!Un zX2#kILU|=7gc)mlT5jR=Q2VWwzMS#qk5P$<1*f(RLD???jXLG9BFsUH-{;HvGXDzH zo-M3PnU@C_n5;U5)6VPvD$kGJgFj?_V;?u)e*#0|hJnaK5pYmGgC~jW=>Xtsu5Jow zbk8CQ$_z^fmh9d((4W91@Y@QG-d9=(=;Nb118U%qyxTXx1IONSo^iJhE+}ByqP<>f z*X$&`YsmT@bX<1BQJuCC$m4F2J}{`G!ENB$G_Cu-!XS1?N}N9sQ7262#-EE+oDR|Itk1BcoSO z_zf0y#1~#&AAK-ho%7&;^*?N!A;Y<#ay~5_l=Un`lm{uB>cn74aVn?f@?X zwF9ZI0lPUbz}TqvHbq)jAa@!1ikR%5)I0`Dcp#P>NiPzY3;;TNN}RY~_PHmh@6F$g zm#q{18`bvFAA#0(RxBV!HDLTQ%|t}qDlPr^8<`xHxtO#5l@#TJA*?>jkFK3T zrLH8&;ErK{V1x{sB45Z}ihI$Z^|;8_gig0Tm1M9Ee{P_uGQY_QIp8UF0Ud7fQ6K}T zTFHbPUnyxt*(t_Y_;dRFsi#iGwme1J_kHf(4s_{Sc~92duk;K4jAW7UBeZak5W@!H zf8EwB^Dk2__+9GT*4tKdhuVqzF?gQSt||aF7`OAzBk<;R0WGS0 zGppMofrSONJqT0$$3f5S0q&WMYVN~Q8+twLdyDHuT z{g=7K$9dLcD^zWSb9F>Wb@AeQrwLcoJwowlkd7SHyw&&ZOs`E_K;%EWux9$(cD7A0 zUzC&EhpGRpeDp|b53sjysVUW*-Wt+cYA>XJ1bgLyC)bACMQF0M2@?#w=h#u)D`Vx1 zD=bWR#PSLa`|KAk%jEH-CFAV4-MO^}jOg`b;7`g=YVY4YpZb`8PCtUWYtMo2xu2pXtKFwuV zt1I0M2i@~#%GgP|X<@mMUi=(<3GxMjN7jp=cg%gU><9(xj&i%LOV__mXxE&p9}Re- z+QW49-+$sX7QeAn7AN$KI!@TvCd_9YLlfKD_4tS3S!#)qfwuTv43=vhJBcMv6Mz(2 zk0&rKBL^ds@w;p-8Z+)>;~4=!QJuVAe-ZpB+JSllF$yG(=}}!bG$%@gttvzcx~<5+ z4n)3%%YT>5$mo}xXji6x0lRPQP3M6&oE!+LLDD!(ijybLHqRJka zXxKNy5R@^b&&bWd(tZHyZ@w=-zbvlDmnFVD&Ub9L5)sVQ!Dt${NL6X?rjAMBcT-oP zz$}7jcCnUfL78WCe*53pqYp(lMqC4)p8u+DGy()kzq>8S?h(hkbeVMum~sFV&c#a( zWvAG_eU4XGJbIcDdrLXU0;C=pmgjZ~IRK6q*N;!AY%q`}s(I>1=0Z zdeAw5JYq|u@p9>JYk%INk2*5+fn*G+Q$*#yKb~G*`lWAlMV4kcO#@M~%cJB-mRU6) z=Z#A@v#y4}H4#-4>tIHoyW*$Ef4xa7QsBjs8r-xVb6Z*9=g0eTCLLjDeJ?|s?LZq) z1PsAW+@o<9FK*9W|5ddUgi5r1#IzX^P(OL}j^8r)_P^((*TsuYOx)3#+ca_iML1VU zTlZBv{JF&&1`d_4MD;}Luot2tt7r&ds`j7o|X*AFY2K7Pr$q6 zXw}Ik+>9hV6}U-<2m4!_5c)fYhW9-CVP2vUo|5aSHd0U5Tv)r)cDYk;CL<#yezYyZ zpd0@}6WI;FFb_jrhVGb4N1Ym}PCa$$n6^Iny>Ns(cZe2iAikOtiPN$XOV_yeq`Jh< zvStV=xPv&e$!CQHwF<$6j06X@2jxcob>mcH9t%dx3p^gb`TFDb5xlm(8BGY(7S3N3 zH!yHvJ#- z^8it3J+alq?L$XsWVpXbTczC0N+9l%!3oa+9}diGN7?EQ(X2}EC)!`a|6*4FEje3dr zleC+3=9`>m#TlVPiHfaUN%GABgX^?m(OHfnT2u8GtGdc?omHA*OSy zUBa%w?1uReY0x+9*l|kW-zp000e`h*SrHXnLge}bJ_Y7QSCdc8RE^47H1+EUbVXc_tm zQ8keaXLelEz0n+lGOmzAzNc+5cOZCB=8e`%v55-3{v&NMj>Iuw1I`88MuC)DyE1CHWsXI#gi6guku#m-Ct*+1&)=x>MQ{b$S2-4CFLC)fpe+$%*J zT-`~-CAOb2txTYH376?H+%j%HheiYm5(sZeSYUY8nns z#fTj&`mXZNFs9JvQUioKZ{z^qaedgyoMy0BwaI$+D%T!I$~+gc1{k89N9SPRw~I2i z(xpvO3)KWeyLa^Gf3B&2P(S^G=A&0(-t52`Jbf*xImO?tU(8FHBc>Qq8HN;6m44*_ zBh_7BYxO+8y^fhz1?~EDx{s+{)9X|p#kt6 zT~dcym&wmb;Hg8P#aQdsx+AKJU%-qre&#-JcYvd5VG6i)d!Ad33ww0mhr%||1KoT8|!h+eQ$$8&{$jv%?b6LV(d9Nu==Ck ztsJUvIix2Sr0|GGK0dE!x$ZfnWOXC6ilEiLXD^zW^Pxo>rAVI(OtPGbvk@pBh!los z7nhYPc*zN5`#EzLjyre!u+spk4O(btS?lZWxg>ncF!=1HWGr(&MJdZU(qf;?{mC|W z_OsUe6K~C$9mhbD0r^z}F|#hqR_g{KNwto$1paU>#(upwHJOk**ka?=?rIei=cntX z14tau!fA4H3>P6KQOcIXWE49=#iTI@vT-#PxcmI}j$RNxH7@OJrGlb2nZI{^dYq6(gSAze*=8CwBKa@?$yn827(NI+O ze1Exv+IUnZyY1?wdJ+)$JHeH#1jhk|r93ETqBquGC@?0?r2bK066)bwTO-s_0CHaC zTHRZ@a{&OUCFqyskKIu4z(n5lg_XWSGujEzqT zozBSdJ}i;T{O53;vtMc_5s9`UO_AV*;ZD3YUc^K$iXDm?2| zY&tb}sZ(bJSLQ|yA*_G9pa+ce9;T&o_V4ZI%Gtiie_e#w90qg~HNXK1fomXfbj^50uWGGKNLt?@>e2itN@KN75{ZL)%lqG|NFR52l3~r z0FpG!;6XL`l{uTPSsHLcPEd3G{;4ju^L9X?Q2752gb~GtqK>eXCBU}ctv95~gk`Bd zf-T|Ee)bKjlC@4aK0dyDN z5@<5{u??kEhw{#WAG=G+)JV((m3P`p+v{-VY@klLxTFB!iwvjjj1H@g!n>&M9IF~}C^|6}Pq!;*a5w{O$R z(iW*Xs5C82&226!bEoFslDQ={_XwdfwVbJ`uTJI0&K=}#CDa<(YCqM>sF96e-LIm~m>=MC%gw7;amcG2h{uPXBnN;UlG)AG}MyhND!WsdtZc*Hb4uS|gv13WTaMNbRnKWgnKcitE|0@dfYz zDx?hYXRhWFrQD@JsCJ&?+Jgk#^>Sux(PY<;mg=fR(=Q3Njr5YXmSFLCA)%ZsvLUQr zxD0_T{=1H{=aY#>icSvFwnER4I4JODs^zhiLYGEiufYr(`UTbYOZA$=6bQC;RlQfM!@Ii9RJDx+-2V%=qPn@c z@q~uqXa%XBoz}>UGaK$HR~ojQq2DTk7fz_QY&uYasVa-vQ)tTPbc?YZ(L$M_-cmcw z%UTcSpG|)G(FOJgU1!%c{yP*IL!<-d?g^+_;)t%OKYG*A!6;L)u26@qAboS}2)aK? z0aNb-o;}ZOeJZTX)58A}^qG_mJxW`kS9vL<$;_O7wavD94C{JH)>DYgxpl~T;v`Vp z3-5zkfp$O(;;I56aCB18L#uIwC&cCYk+Lkwy&jE=F$(KVA}U|_55|$LLPv~TKRP(s zqvD}7Q2%7rPYYixFigqX92wu~9RFBJ%J4rVpmKFq*Z12FO{t~8ReFIG@UxIPGAk1$ z8k>MC(YgNGPBA2kQSueBgS`rw&!HSKikn~09b8MLna8*8xi@c59jJzV{*mEU(1`6K zqdqcK#{^00X`!Xd(zhT@2GD#2)e5}-zlP_C822}u(-O^)```MH*th>!G@(B#Fp^0K zpaq)+@M}dKCdED2)B}hjpdi#RZ#54gZUxzTtn8)e$vvIBQ-^%JBRX$J>dZS7Ovk2< z^cWCPP1t#K5g3QK&OD^N&Zfy>&i(pDh9++Woo(5Q^LXi&M?(}Q$K|s|6-{n1Cie8Y^M7_j;w&!kI~ ztlP=#TI7=8>ORVZdY2^8uF6f4%YIupr|seIb1+9N8Ej(t)**rIh-RMfZRPsfNQ!XF&;Dg zN>F}=VmNMFJgTp!3f6Mr1TJ%bA7x`bQNU<^ZjJR{_4~c;lwBT}&B2rm5+E=bh3POp zOf5_}-HVrS^| zwcjegrH`x&-UG8}pZX`mWN|cADo_{gi&GVJPYqO68lzx)yquYrkui8vV%8tBakGWB zUxI$YqmxDR{E@_4;6Duk;k7M@#f8XTZ|R;;v?OG_<(T3;Qnu~vC25X)&6J&pYH#!l zy%PQabFC=Jx~d{~o=@%RNUu&_M!?DX@<5{`!@6UU#&WvaYo&J#Ds#txC2qDwMRWto z+2JJ~c?X@^^=FA7OWN)DJDz&TWz@ueA&vY-p}}+xFexXFd`ygLbV&}HYES#HaaAI% z$7H_vNh`gSM{Cqe!e7fs8?DiI>QY$tFd79{k*sw@{kX>qPi4)E6*%$>h}97B@`&GYO5*H* zZnwZA-RKMv)bMTKeH?mizYOO5qF`$l`!Kid0A{>e$W}q)TWwRhV8FJXFgI6KttJ2D z{0rq_DJkzEO(^_jpny2Jof9KQLZ^sx=a}97_kM6)cM%LSxSLn4)ql4g$Md~Gb{sJ< z2jpitgf_ZP@~Gh8nRAQ;rb=mVd0f0`Q9i0~iX%b)>T;=`4?U}}1kODo6gN|Q9y>

    o^1?)&%uv7A^X2@f|Q0QPLF^^? zph1O{l3~P<_sUVX-(d17;jS+f{@TU4t90ukO_Hcttk97W&Hj+{cy+P`@Lk{}=uS7n zHil+6=&4C`(O%}gi5lefgMo&dF$6GWsC4rexlRPS08Lj_1BFH9-!@WE3h*7%vs{@z~qi>LIe9e{snTF;*8r1`MO;mf1$s z4BGf@Z5j1Uu8k~dAaGSR+aWNR`QCMRsU7P2!be{GfbUTEUWP5MYdX)r#)ErptH)UGJJYV?)YKSJ>_8Xh=D{sFT= z-Oj3<6ZP&A=&h(`p2wHS(6XA?Tr$Pg;yW8imoc{ftALY*Pr+JKCK~O<5Zufi%S(rO zs%E^mu#-)6du_2Z{pj?(KMvfJ36sw#xjvsYCWK~FiAK%7=ASblmK6F8iZ?slty~`G zzuOc+$_+-mKDeO35d9Hpo2Kj77oBlv*zePra;^O}_ATt?tGb^e%YlSty69-CZ@0-} zP35p_$Wj;;?Y#yW%(rF^eXo#i@>$Jd1*PUR*1R>RYUo)uw8RZ@FMWC79ouJMZ?khK znxYa5>;T-bUTcKe&OEQ2`lI^F9QA9l8HSs?x!de!|7N_*W841g1GjfR3QHsl2nZpp zO|UiS4(|()TU|D!+dfh@Q~3f=6ztx#JTFmg5&hd{-w?X)b;LF9Rw}4SXm9-Zcboiq z^*EXds?6yq;u_Z$n#8O%GrtB|w~0M?o5wAXwx(*~7ν5qic=WYF=sJwGlHV7A>F zmD#=OR{7wMtX$K(bIo*|N@?E`DWYr`ydR6D^h5r%s8MQak5x-^ZL-wV1#Ln;a4`Gr z9$WW89XZT6iI|`f69I@jfOr62aoYJ0BILkg z4@I(5Q9t{=0$hvRs$?Jwl4CqfI}AXN$X?J=_9$U7-&O$7!EQ`Y2EnC!*QhI(ZFe?R zn!|;?s~PyUi`OKu15x3|yuLv2FlHjKdpD8c&fl89aO-QYZyP;M=aJ&bXV(L5{hSEx z%;T3H11b$L^ym`gPo1*)BG0yxc~JSv-k8bdrt1g%dFJxhpWynM`ID;&pVFY$wMw|^ z##q?t7vfxAQY3wKdQoepNG^A`UyBdbJvlL)al@9jMx}x56umTgwIE^hr>w) zMZ57e2*X0EdD9xQY7`9+hPjuw6FacVX&d_n|L~R#T#>rf;i1+qaVxMi%VY(hJ-t?t z#n0i&WbGX!@V&s&L*F3R(?~Rv${@6f!+U?Ag&CoXZgwGGZLVn!`W95owbVFXXvt%C zZTbdz^e?A%gJ)Hr*fWtgS5rI;8pe2KkO^Skj>T=O8$c3cJUt?N!AL$@_Cfr97IHHY z86Nt3uIfyFjM$279sx_c4OqW7Ut~`xX=VwmxHUTVM4moULfT==9T=5*hw^bZ_+Da9 zEvAsn@^DPmPycrgubWQ+f4R~n9F;?c{CaJz(!O_(jy5!A)ank>j#3X4kP`Dq8N#j6 z;_mC;S_^OWn&(&UpB@sDG|pK~`>Z(jDdG`BBa-in@G!^61rwPZ) z&ZTWM`#PchqDLNe__!iM_H*?oGrok}crkDC>q{S`#jyCO9wejn?A`dLH`o^_ZLhXL za1hWl4%*xWyZiKEjLbNX{G9wLS&BLR@<3+P~7ooFJH3|(-Vh;FZY&Oxtx3P8$_d6;Z`dq8YalDyLX z)E&rf7kC)+fa)fZw8&-@^4Wx0ODUw^c;P~6Y4F_6vqY|)ZSJ#GwK0Vd2g#rEiMr#E zBvn5md)d%n9b{42geh6uSg)A`^KfV_QDr&LDCGQxupvXMvw(xS(0hDs`cfkY{WfGm z@XrS8cPv<(V~z~(d%Id592{YPVEII$!B@#`gvs%xXn|3dH=@%+JAho?|3i^~i}nNl zQCq-F>x|f#>NV;a`0d4VethRF$HcOxeNYd|GcT#uqSVtSW8r3}jMEH+Ay4F{ z5nN@+I4sdmOqc>4fxtXC%#_)njdWK={yM)>h>=fiK@a-v=Lf>3K#*tKvyRLv=cFo=gng% zL8Hw}&2PV*7|njN1KY@^3SrwA1`Dg(9)2iFR4PwgGL=rF+jXn1TA zBtQRzbT)gjG=F&D*Do2)0^x)w@qGYxMQeZ#?7;d$HK_m^hd7Ayn#xtLCw3p}mB*#4 zG_?F1ViXuX4=b z7m@Vq9_N5W6W9NBM!XDBN;h_l38JEb^Kktgcrvil#zpaK_Hc6?(98#A7jA^IUh~j9 z!gi77!d|43Y~vuSRW8{f3|bxcdqgtzF427y75%_F`=Fb?dDuCw{J5pQqT*pn4F>r$ z{t}?+qI&;-lSHvY#>2(-{$uG={NG;8`N?&DlZL_me<9{;ob(${C!9%z5j>6Sd&spO zs?5`&=Rvzsl&VL_U;ndpNpM$)0}kuX8`=SA)q}rlDdj7oAew2YIDX(l)5F=?F;|+W zW32bVVhhmY^JG5MW2nEA4TOda|$P&HI6G*?>t1#t3il2_p_(M2wTkC zq+zOir){HMl2qAGp6JgQBW(gz|1tlMv^DJfw{ciLm8~Q7LQ@|37H{BW)n$m)5waa! z?T&aLt<$lT7P@2Lqpt_AF|X?rezbi$@o3X`G*-#}s{o~9uGcXH*H-Rz?C?x7m9bn_ zevM-k5m64;A#TF5uBE@)N&ENNn12TO9Dj`%Z^7&)F=k4UrI=eBE-$=~_CzPPJV%e8}q^n3n6Myu}#ED=5PFW6A=2#?k8FtfhfB>S9ML>slxUtWNgqY>A)CAmc@PV z)=#a8+cX)73PNaG=MH6ADN8ewgYRf%S!;AyybX(*9-`|CM?U;pEj~F(?Z5etI%hK3 z^g z&&{vEx9aWRY4Sv~)oS^QhZ0MztN%8;-`ES<9$vih%#Fv@xhKQ9e%V#r zbteS-A~{}yRJc|BzdTzlz;-$**V~mg9foTR-5qYQ2D47PrH$SfG}7pqw@*E7KK-VH zx8y=XTzg=CsH||pvxL%$kca)gy|P(-li_D5V}l=RvoH0lRx8ryHrYjom|!?~OxF6I z(Rk#|Q3b^#;qf5i z;8q9kp|?S~mZ0f6?1~a{{yE1QM3JJTBE`q~JZ^SYHi|3Ny`%!9Ib7_Hxj(YcN|va| zLEHV#{>ETg!hfaPF@6*@RHfjxW?(!Qx#MX#{x&Kyd-zj#_djyJM!x1-Zb+@yHdoe} zA#uMJp_h|oVXu<_AtwF_u8!@p!7vsAH!bGbqft7u{guU{n|a zYp}oR(C7Jd)fd4sCP5V%{OBpm5wGa6C0VUj*d|jgr||fdA2|IXYDhhrPf|nrVde#V zVUsS|Wk6Rf7FN8KJ~hM-0{|Y~KVWH^5%&07ieIyMs;sp%C~u6ekH z9U^H5jzagR0?oq}N3z=opJuUVs@U_`;mMVM=$6!L3)q~E)Oth~1F zOenk6ciZ!0rWv8jc-r)l_-ZSj$(zv@>Lph8gMo*Vvu5r)qwPJ9Bh?|Xp?oCRA0+W> zkfKL%>hfD>wbIO=)y{cHZ; z_k^SB5gJ~5L01U#cLl1g2}$;qo?aHk5FZFhobQ|RZG2)|m7I{Qms(uy;Ms`CDk&7a zm}Kg=nOzGzjiy(##1~q9Aeh_ph*T1Om1UkXa-|#cuUxD;iTzn&%IVyz;kB)nhja_l znO$YVomVr6RAX8=>XgYIer0_VY8XUNgI=dP?+pghs8KQdT}y~u**$tfm42YV@dr%u z+=t|a-hXTFc_q&p;le3DgeF>7y~-bT9?risE@WE{*Pns?`WvO*Hyt{=Pl?Z=92DPq zK9#~3Dx&q``us}tSB=XLf;OY>>iv+I9n|?QFsTC5{e$35vK_lB$(`)O>B?KFa>nJp zrA__egCOZv^DLn>g&Ym9hYN2WdF6+KauEHS4AiQPCMLje52X}@lbryF>!RQfHPpaP z9+M1bm+f=RHM(Nj!M28q=x;NWTWqDkVpvZ}|KTNaU2{}og*d(~npe|@aqsQ9a?IhX zwWdTad+LFr+vwL=KoX5-%8hdLmnv2VS|n)EE<=(XH3{3HjxIMdhr8y2+ZN)1-d#8N z0vy{hS<)+!p}>EaduHk98Uc!NX^w_mb72FOoCOS3R`@czL_|Aa*S8^&z7IF@};GTNfnOZ$vkxsXsiv*Cj0cln83d*n{N?3`u3WpyU( z+K{p-|MKpp%`mV0$tFFd0r^2fDnx2kwoC7PoIxsRtuyD*?O*pUj>$kopeXMqdxu<0#o+QN~Q?YFE5VGQJRw898ZE4 z2}G+S`HnQ0dU2N|8kRsCzg(0eQb@H2957ty9h5l@?1*gT>IU{m;upWdvS)*&Hjko? zICP@<@2D^}n5Gm>`W35DZ4&F^btHM@kGUvt#>C)Z1y-x=E?{y$Href65vIkMIZgi_ z>$L!k3{8jvQX7B2NCn1;ZX>A=LgeYP?XisQt6lNO^Y~5#OEqMYn5}UZGYMGZ`mH`; z-FY5CRtv)1rckpLyngucV(TLppx63{IUj-=J>q#<4|^NiT3y5RAD)JxFL_n_dhj(} zSn<<}pX6Mo>-opNbgG*|e_-V*bF`O16(`$!+}*-04-hu{LnDvDKurY!`u3}EC9hA| zs|WE^^=7uS{Bpm^wI}L}r@BR&B2G-|2JmeHQjinsV>Yo4qZkBhGXjf?y<#c_^VC0I z#*+TR*0DfBbcg6JKOI?14bExj)Fh&k3*9Jh=p`dv2|EguyDwaR7;nJ(I!%j3655R5 z<)!EekHU218_i_((ZoipyE8{e0tOb;!(*ACo5x#<9Dgk7Phj9)N^j|egInltpZ=r8 zMm^4Xm*3zi#dbF)YYJiEKbBZNU7Wp-W7_?$rFYy>S**l|0u`5hR8KL!`60JGjN33^ zs=qf0NFpJKz!Xb2rQF67bbOw_$dOugyV&&oTcy$Clg;GCz_xOwwwro|amqJj#e~NB z9{<}=)a%RNQHBIH{~-Um7ijrKGEKnxJ;T26sho0jt4EL`hRui3qRAxf>|p;~#t*p4Vn0M8y8;K?=kd zRT$5ssHv-69E#c&L0UBdbQa1We1|%DR`5r^?FZNu003u z&L=ol(gA2Ms3e{(%AeU@jufg>*-{Y?v55|vops9wO}lY8m1_%n)TzTiC;=IDvnNJ5 z+Z$!%Pn~@3k&JAdV<2k72*`IKxR13BXAWY9O6!as%WJevyzg+QD-3zcTzVnZxy_p` zniGe~PSzJGbJt9JaQMdC@Wb;hFZgZnr`OG?Hi~<(fSE4&_)(CY!6mmt{GsmBPP>-D zk8X$k^&=A|8`Z`8ZIxy6542ahARM;_=`5o=l4L@V;VVP?;}$DU|CW&F=C=p2<#5Jp zwKR(4M#z=iLBRwvK#qlQiZ?7;Pvr!ZjY!8A1XT!$Cdn{Mjf3L*m_rH9W@g4cSz~tp z;BBrQ{`zJ1*S3E>(s`k&w=kiFKx|$pB=Pa|);g^ZAa&3Sb<#GPTQF$*O~54=Fdh0w zO96EX6z8Rt)yX4Ks8jWIXfQ|`*NBU_(~*48QNLLuXTJ9cG_eM)arqRNe^IL6Ln?(O z_2VfZ{A}?T5WGYqwBP(FXGSX36AxJ0W@SklT(FA-?)!;|J<L~kS?OjSV0Jq48@1$&r-Q6Z% z*sr2rQY3kL>;whZIYBQ87T>L!WiSl)Z&L{iK9Hq5NFqO!Db)BI^D62{d|)QcJ23=5 zK6Ft7tCP{odJ!Ta5Hg2M$kP07)~S__IOi8K(^Gc@s-WeP9 zL%^w06$~CVA5tq1Mr}*x;)KHqn4YpP=oH_vuVk9TL75M205rTdP2_*^Qema(0eO~gwPK5mqy$gm(fX~u!}`AYB)TJ7k_(k@Ev6`M$bD(K5^dh@pgmtT03c9c7*ro zu}+6ZW5Z%G$ABDr?H$|_M$xRU^hbZLZH@eu8fghr*{oMDkJD4Ot!7tEY&*C1(l?=M zh;A%H`-T5~Fhyr}QFBr)n?mWdu586T#uZ z4as&o0k-;|p01ku5^Nz0p6~FJAC9VZJ8J8Dz7N8)e!IvnVy`K?6~mvB{P6O_-&NP1 z@jh@k^-cuBw@D7#?U0(*3iwlYL-5o`!{G{poNHxG@;{iSZQ*U5{QHxs zvuE;4rDYlBb0-oSWu7W@p%H8m8g+hVw}Jfh!kl$iqjyK~`I zLG*?I8h(x5JhYVY<8}PBD~EaoB9o2yFKHYdK@jk(lwJB==P|I1pd-=67o)x;DgM zYxNic1LB+8XGH&Cz_rJA<)vB<;cRD2Pv}ZZ3ZF1FNenGbOKt0`3Y|Tm0ql#@Cx|O4 z*cy&c72+TDil5|yD_3_}98W%lT;%v!-2Q4gvTdNseA!$C(wyOT7@#`H2*=JRW3Dm2 zh~FL$KcF-$R(n$RW-A~5F8Plo*yxr4-&u{tj7>T`}%|T;wny6um>!@Jpx?8E>D17Ky`vYN>Bz* zZAdnZ%KSZ-`ZRsn?6kC}2sDuEC`dr$2{_lV{Vgw4dEa=snruEq30a?}Hgq@2+e#qy zWPzmRMdaDXcN)z$js|5ZIQk9M+y2Lo*ROi?%14%;1K{DM1Z%c{;a%0;nRVz7)eB?F z5I{xNq8hmT*ch=|%jQ;=c3E1-d+fEL9yh!S*I>D=snU8k^7Q-On4$$E&@!=e9fPmK zq`A9+`ZCOR`hzEF2t_cf+vTKNtDZyF{fnT_l6V$z5nMYoBCW8EXts`SHptP{- zRn~d)OFZnenY6fb6=u$p>5B5>jWzCTt3z2w$Lw&!N+Nh$Vtxi{=p{0aH;(T|?ua@` zA=0bu7LEg{c7SQee7iMp(V$u;Wn|8JGawwZMOYF)v6@@T(SzY5QYt8^KNz#Hed&4h zHhA7(N_XLG<~&EV)rYlNp<&LRq2_1pi_a-=mXfC>#j|hzvEDB2#%Y*rlQaVSeIRTo4VkLU`MvfH1jO9Xy3f#&`t}3ezLJoIF&j8nRdnQmaG8F>N-`35k(ls z(P6_NgBG&qH918o9)kcv-e)Oy^p$iK)fsrKV!MJ|7mywkUsB&y%ZmT2aAB{vFk z5^UhSoHk1!GDgOeUG=k|hNINHytz_qcucO5RELq_gwA<*8hvnNnJW%^7wOf7X8uKp z5SY+8n)&8STflotGWMH?8Kbfp7`KeI% znuP0c<1n*u#9RGlVlL}Bv`cwyT_g_5<{UTGF4t69>ttk2LQT!6nx@QHTKiOeIJYB8 zVuzl0=jR-gYnIX&s^gNHk1s-%L0pj3d%K@id0pjb8s#qREe_5f?!obU&aoPA<(7I@ZxCm0KFSe^5zq432#urmdK+Gf6?y9~}Z#o%gDo)Im31#H|s5W>=Fk zqe$1KPy9hn0zlQfci7=Yy_^oP+Y_3!4AF`9&%nfjQZZLl~_ul5Y5}Ua^q+& zf4!{Z#R(GNg^0?2Yy*RsccJEE zM1|eir}&*3B!nuwjEsi>9_A}>>6SfNJ@Jk1)Sv!mpliRsgivIo&%Rd{LpzV7#!DF@ zbEdUHp10$I9Jw45)I>Snz`B^XnC;9fB=?#$xLA&@{N10uorofR)_L`i(V#@B;Tn&X zIwpn;-U|7exsGu|As@6Zdh@+WziCp8bsH<6PP8t=R!H4`6kz)Mz1Coykt=$*}# z=%t&!T77Y>jC{MoG+h{P9m0H~@$!R4wGMW#Fh@oVAc?=qW6Q!W_DoG96qu%i8#h~9 zc#;p#uByZatNui;q)g9<;KQ0-Cm)nv8gj02SWn`tKcJb*6l;jisP?jcwc;JJ$~6D1 zEWr7BafVs3pmF8*=2j>yI=c;T1w3abc5)=O{|63x0sFVFP+lSCkT#QIvBYi8s#Kak zq{?eeT{{Z&-a&s_!fHT&9(DvVCRF%F%#7OlZ&ny8PzYz)qvJi_khf&7_>!$+1qHF>MB_Glgy zEm4zlCT$;hgz_lyvXu1G-bb}jlSvQUt<00yAI?TJqjlVb@ULbVG^3)g4 zFDW*|zma{lrVhOM&39G~@PbsbM)@&}Jig4R3uey@@a&;Pg5r%K{%O2E zQAUVO*GX!w8@5wEHg*n}zCX4qTo{a$4$A6T{~;n6{^SBOUX@X@TuZPi5gTUY$Z~Nj zIML*xzn9F*=qi89wq!tw;LHNB(v>isD=W$U-WJ{VMfb$^?X19;;m*Xe$$(t%>y#RSB8qzU*l$>Oe%m-%?dzBp&r|e@gj(US+PR4FPA(i?j_rMSu49 zE^)j`wt1*V`suPIm(RKKViUjR3S3L-c;Pqu4DUz;pnoa9st?{)2}5h{)#jjRhIM?xDt}H^4I0v8as(v!9hQZX}XlQl|lo5C%oAS zcQXoQhY`fB7chA$&yX}((ccTd61D|_LG3F{&Za(;+z~KO8u(CUuFTseM(f4OV$2x^ z$v>)t3TNU(H@?O1;MeZYxaI%4@8CUn1y*V?DB6R`TRCcIC?B4J_8;=X+5y@(_C|R> z?w={f8Z=Ga=?|k_MEGxJ3E+PaS7NhE#LHQMg(ZlzKSno;+1-luItZ&SDvr^GkMW8ywK$ zy5-}4e`2a8RYWDIKd_FUH_hwZuf4gIul#3y?IMq*nEiDj1L=?$W$5h@I(J^?Uf1uH zgZBcx&wXS6osMhxy($|Z6Fn}w^oen-&Yrj4T4EC-ps|X)IpVPTPx-c=Im4uZVr;St2L)d& z>-SQfJG}I^28rH{vj8fj@pN*Cr7+0Aj?t_f?C*6KJ5>g6_>%joNA=@NN^$seYh)Xg zdhI`!rKg5}B#we5=x307n(uI)L%M^#R^yzimZ#9=F4J{~M{Xo+O0zFR^q-;fky55= zW&ojymQAD9}dVMnGAcB`W| zLObjlB2fMfs6Cm3!~)?zqv)($VR{`|5h<{^?bVmwqc&ITF!?x;-0dEoFQ2MD=xY`5 z*MZe5WFT)V6mg2pF+osn;$)ql9tdS|39B!nBJuqAS?MnHIieSNQXrAbpJ4=Y9bFl| zqu_J?OxOPDH%eKs?#@@aI=p?f3>DCI@JWc%x8)Cf#_gAX#lCYb8&K0`j(qW9g(Lj8 zX(``ftp9HB5#qQU|JWWVN|T!ig2*}l75P%JWm`}PBNSia*Y~- z@6pM(QP;&%9Y%5^eFLIYGVTQ1)-5(qEe3X)5wB-E)u1EH!R=dbASVtEDrAvv){&Ka zeLkL@@{Z;w7FB$_uGq;8OL|O`_2WRrb_KZ7h@RE^Z#UIS>KXaU&zz2&YfbkrvqKa` z-@)z_MD0-gu*v)=im57&EMPC3EVT2j!&58EPxlsgnL@dv0K+B>vXuo3REyKzo`i_2 zt%u9f=xc4z#MQ0FP-^>O|1GjhGC!N^ z3(x~qr;B~P2?@V92X&|$y9+n+FFV~JORdI;`S3raS{FYnPuGnQje}R)@$rLNHBhSM z0bT}VIh*g+eiBbHCjQ5=eTK;Nipf4VKlf@0`^irbj2Q-c&yv-< z+TFJLdadqKP9k2y+pKDO(TqC{HGdjOEvc#T9<#( zFkT~;?mR3+@D<6@NlJXo#i!Z(dn+K1SsHa%-1}^fnMglY#S|c>CZCMu=cSZO^alsp zs>sa)yf5Ux)h8t3cd3hqeZ~O8Dw1urQ*w$T)pOD9u`+K;_{roxi{zhrO&bKJ0@KsBd}GHZb8*aw4-twAMI?Nel7fWsi*Y5nNm-xFuHdq@8&m? z%=03k1A~R6&87c4?qTnY;Gbk@$sWChLw#7H8SqS;F`&Zuvx`)+qDi@Gb%4s*@LQ|- z$<4hdEG*{?0oS&$z;YM(3j8_MvY2|RgR@b;*g-YB*lq7yA^NL_>%Ra9;qM5YvjT=? zZ&vq07BVnBdjqB^=X1==KjUtNL4B;%bCIn^s@!Gf2~%qjZa-1vOrLRYSo;+T1!b0V zr#AAI;Cb((jaroevmh{{P6WdGu&F<_4PQAHYT)?6!oGGKx@+oL_aZy!JXm&+|M6EA52 zvd{2tMS({Acs@nURSlB)IZ|NFRHTDY0xW3oVkI(H{w~0iX;Byr`#2u27MJhBImlY# zhH7TKq#7P;1Q`%OId##cPwoy#Q4+Jog9aP3u!ae?6=phgH3NX5@0q{Sj@GTMy72Qf zB6(lF6~Jesl( zkQMw5Y_;zNh&99)$n)?gp9RKVH4?W8-gTyKKfQ8GVi32?o83ZcE2>@iI%vMW zTsmBuft?PPn-v%tHwuEKJJe$GCF8rI4(CqN?TEYWL1;I{uku$jpW+ejRnu0V7tY?rjLApKUJ_sLq&Sl0YY&%H}0P4duDQ`P1E^LHq<~b zgFQteb<6bZPisJBhfsa@)gQa}kT~Df#DhSvO)i%N#3liTT6~21&g4c6VT6f&h8_Nb zY2h{SVB-pXm2@6#=G(w9q-!j=-L*8RYP}lG^~Msi`va0C+EM-vr9J~&iT{xsRcLDY z&F&%N`&Fczhxq1-=QCrDrMX2>T(d8+&5Q_-rEEURVQxD3$PY!RhX%reL0fEsQi7Gg zx*V0hjwY({^*KMfV$1ci^kNv*OtN#-O4oRz^%WndUq$>oRBod1%id0R4ryWT-6$G) zQF9CTlZqMEe&Ap$MO_XPdhQvDR{%!FFHc7G7u z=%=o~SNdCaQtD?Q&p^RC`^X)c@9j$kHkW4HpGooS5SASnqUprB_5y6f6?e(5B+0>y z>)Q@Hk{uy(QQ6L)xq}m*Btxe8v9YhxvI=F249+%$FkN`csBe#@@E*J0s@M~RjSoD- z4rH@)f*mZPyQ?Ga4xXtNKoX`AkIf5h+(e6}WPH_EMEO6Osi4{b*g@Wx%E>|{9=h9G zxvX#iciA<1NWUPRLgw*%ShZT1!n)U5_Nc5JB@tm-ZY}&pw-}sk^|JANvPkSxCjfp(cS8^RX*oxX>wd1d{)NrM zMBu~u-FO}96eWDLqS<~iJ@)Cg1G(V0s?`}TmJ{^GG@5bS&1ZJE#?1AaEsb~zPb=6t z*smXOgH!YU)3Cph>}>_J)|!Q)j1sxe%c-kLta0bpsjqTVd`I_*7JWjNN(yLUd@qe2 z|A7gjYcx{L3B8x>#;~DMrqHdN_F;EKfLHHOmLm?~b7fQkK! z2s1jz0`$TrkbR1bb{QA{S^L*tx7thKwyVd)*Leb}MbrLR0sgG+DD@9*6-|>iFAl5K z+8b00i~3a`l1Ld{L2V!amf6wSjPfWdY@Yd(RK4&a&n!)~nd0u_Q6bj+Z}8Vl4`3qH zLgg!8BH?VtWEyyEi26;1)13;Jg)^$MU(cfm+2#JDtvVtkHosY)Jxfc-NO+8$WX*EXK%@TBpQ;t?0uzkF>k{p z%&S|v*Z=HfUq~EoyqT~V75t@QuCbg6+V`K^8eBZez0fGu3K(%d10!_vy9CrfpfS9e zj}fCor1_?q%-i(YmW!%#AAtHXL^*8&abNWKQE1=Mtdi0Al!=S%CbZgoYmOtXpdRnP zj;)3ZjQK0;JtnhXfdDkhPwY8$A2uZ#1OX5awJ(ai4PJUYLgU1|nv(T2vBUKikUx6$CU@gUf z;zD)q?IVXs6VAF0(SYco?xX)${QY;UB$0rUJNc0Qyd_L$_%^ejSdjq4j|lQSVL8## zGWasY1uxV*+nohHCoQj3xaKY<(Pkbpw(;YGn_$9+l8=uBNl~;=tP3gxfq@MqqH}HRpz5b3n-iZe7_uyXBeKw8_zDaU z)nH+|w2&HRGwL$_WxEMI;xR_3^xFB({cB4~8vV{kbVT_~8T=X%A6;{N%!9n#;SW=+ zG19Ma(Acv6=Z^wYN%Nh=!H&#V61k)cyw<(%tq4G9F%UtFA9HQ2qy-Iw<$&;HX zomi$6Adq0Qkz60|wmRNqd#8uchON#j^CBclE?#;%cdRG}O*0Tirr+XwH(i=_@Y_8u3Qbqt>`wNgEAubhbuu$~Gf%r>`_(Gl zJs?38-uHuD&p7Hv(DdiT3q21)`HJrv5^bG?QecB70J zxA9nTm$_P@=&71^LRORBE4udZQavVNT+Y7pp-TAmC4c*MlxI4#PN7NEQ~KX{-S@LW zp6;~~nbKMIsmvqUhWz!!eyMn&$4c~q%5s67hcZKJkm}vG{{>sec)b26HT40AUpX#% z1j#n&#Ee!}#~akdDGWKp$+F$N_xpvy$>v;&22p~-@qTGE&qlXIl~dsKovW-XzDF1K zk-XGcxWGbs|C3bY#K)_s;LqF2hEBaC)>)$QMDFKds zG~fHya}d<>rX8ME zIpz>y#mBK&$oa4$$Az5FTao0r5OQ2{J}!qjvoePwM`EnR$)vve+lb+J58qAoVZ(PKDT98?BbQerkt z#2lj*c2!O1P8<)>Oyd(OrY)x`ZoN!e6&JeSVII411_%8hoM$tPod>?nr%)U6pw>?hljvpsVulhGl+7`9ztQtYn8u&|&dD`^MIj z=V7O_>hy&%k4;n_rM23AF(1Vuc&v_Qq-q?GE4RJ3A|5b2ZIU;hn@ku5A1XDN-P{a1 zn2q(l?XD10e8orbK}FM#R{0U$5yXht92?avWBRGk4!NTLN37*5rpdULQBw75GWp6v zPn9b0LR7mwB4zuacgRODl4>>ytBU*)ATM=Ve*wwwTJ6%xH8dv0zBj9;w`GKrKJk&4 zRjgK8hng|BFD^0l^6lInEQC2RkxIY*kA=NekZOtdQ4VcQlpHtP?h$cYWN-p>6RUhz zMni*9n_);ru79YJ-u8@#!=!gdu0bN@OLT(K^TDds#pz^vO8FtSF^h$Pp$mSq;a9!< zLs@TJ>kY>5IRA4HV^DiuAFhA`SOiKzWfFAA&5o2B?Qm-Hjnc5v!mVh!*kr zU>iM+Tbpy`erV2SE8pDp+Czn1Iq%6|qEUpB?@DZY7zh`>W~~d&aYqY|xgT^iT|@t~ zkonwesa;Dp(tNkWg)y4wLV>S%15sbjXb>EBAp{y)Fe5h#7_jYAMB>kOQCDW=`5ym4ztzp~43FC}O?Py5J)R-iJ%92(P<>2?uc4{poG~7XF*P=xBD>r2Tfz@x z-ZB5Sp@vvVn0NQkJ)_%SKpDS~YgR8D1RSr*mbBh10bT%t@e`k~3e~I)9ZPACPJ^dH z4UY}!Y(ogy5P4)Qm~H!J>f@x9(S1$Uz5$0h8J1l$CD9XamB3QaTZ|;68~O_3PqzFX zKFds_r9CJmRmPBeGeD$b2>W6FF<9f1r!{I5eQXsFPO+v&aF*x(Ua{=`c))&+|Ke;% z|F0q=j;|v| z(`Pr!7YY+Zn1g?PuM3a(r0HiL_S*8InSf+^yV7!_BNE zmk3w8L22J~lhw<3>$s(|XQd1tpDD?58A!(y{9~xEXh#sWeoS#Dz!9#5*~076|6@*` zlW@^;faJFekGkPrUIU6v7sOp)F;~&Jbo_?p~U!&Wpff!d92VDbRia6jkuT znK+LgWN9QU4tf17EAu3Bd@VNr9{Ug#`i}+JLTn+WG?cXDv!j5;(He|Vx3Yoj;DbgT zJVfxVLqGeo(#3O0JJIqFQy^FAh+IL*oB=A>OP(Q3l4q3Fq_s_9?I zIT5;e(vuUyJ3BiQO`!ARiWGlHP=S#PU-w15HIWkF>Z7sZ>UlQ0gulp$pu;v~e6}#j zW}?4vJ=L`A!3~{>S;JUxXS2UHb}X%P!A9ZZH$foD(@ZePGt*5%+h8D7PA+tG1<;OP zKzdmG;lg9a@&|T2-PIoeQ_cb#sUx`S9pZj~_q?za#WDXvlKrh~XO!6Hf|$IR-g3!h zO-N7rx*Ui5{KTuTs;K&O$BQ=wXHkoKWN$D`D2prGMsig9bhLQRw; znLJPRbG<4(6(nNaB~_WEumKV@T(Ie>HTm|?sh4FeBt3s*GUW* z=QTW}B z?jK9HLx>8~CVS|m*6M{uD69^xBp^ukXJeFW!a;=+CazV&_0TZn(Fpe~hm-4%*uXQG zs?vE}>?L<9ssuy}O8Up5F2DTD?N(6ct)zB62Fj0-{WVc4Qep4m)x>peFP(k6T%ZuF z3^!rbUdQL2TsVOjm&)7`Ss3tp2P~QSR@KfX087^{T|o7v@&y=_x2!>18UdIRmyHI5 zx%owqMiXw$)=yYpYekFme8uad)QME0cMPc@$F~&zMuYO@69|ow_*LM=oqaXpTn!@Q*J*a zC+MYWz6;gmpJ%^f+%XObUPC?hdHKCvu$M**r@1RKHx`iEJPB!fA}Pjm9J{ZwLC* zMG2-svF=s1i=lWD#z)c3`$d)0hiBRgFs1d&HHu4CcjtCNt~6Hs!va!ye9)0NJ;Fg< zf7*J#dR->=hA6HalngYTLF0vFsU~D)8VA@KP?KaoSkhT|{-gVCP&oY&A$|ri3BJrW zO}5QDOMxc zBQ4}U7>_;+3(+GhexWFvj~6_8qc*N|Q&uhVU6(bQh!LiSlNFznn-7CpmU?tU1HGQq zvld9R2)$*2oL`4H@1WSp%BoUN2KFg~A*$armnJOTr@TB$H#= zb|={XXn*%1qWFCQBg@_0woS~{gqO22rg4iyX~OQ$DR>o0t|S6d9#HtARnl3RNCn9n^CJpak!KpEarinorXkrV)8+}bCA)DOv%zrn zr(KJY6#U@mI?^y&@xAI^ndc-oe$7k>_UBI!(|5pypyucGkbds@`#|t-i}e+=`@Xy%Od{i4 zo?Mo18v1?hOiO?^fQ5^SCCbfy^LB9Kls0$qmGsid!-G;Tfp^dFzqnQF7tL0S=t5d` zkscf^6X64;{)SZ?d*_$7;>Q((%w87gQl^zcwJrBaiOVqseaaJRuN+QK%%bES$9(11 zwkXv?X@!sK*QY^xsr<5m6|V!{+8YWi9Kx;8=W=E%^nvsC!Ql#b%)G*6F)I*SGg{Zm z{Z;W$6_t!0ZQMW#(lV=<;9ncSBBP6&KvjG;F6WD%YVFAk{{aLZW*PU~)h_q>o1C^X z8aE$$hm>J{(N^6nh_E{4CqnrPc=B|8qONXq3bDm(rkZM;*uG(R@{&Ls$9h zJ69-;^ho2YT9*KDaIO1l53z~<_Y=ou_CZCg3JF|R6Wi>=)JI7x6PV}Ij z1(`J>@DTO`z@{0M(pc?Md&no5EqeU=(D}mIve*axrZgu(D7O}Yc|P=3d7=8m&U^a( z3fuolOFBft!T3|a6e!R53gi&l-lpb$>&-74Z8V4;gMATzE*tVTmG`IRZ&cU!hxgfX4abm=#cF<FcHaM94)9u$DqTA(qYxu?;(Oj= zv7Ii<3r_9sfH{agz)PoEGE(UdH+DPoiCfPCEi01moP5}hXYqPGf%jAr3=$Goq^K}T zd@=a0??~f~!F+y{sQuEqnvu++-Y{<5({}%6o)sO9b|MV-8F?|bBt)_B16vyc zRKFSrhm7rMXS7Mv^{93$h9u77y`J-|%g#HW@_A&Yp0@^vv?#wopCW;ye8G_jQ7mp~ z+p)U2>XYsTvVxF;;8~10BLV5cu&2Bxs|?gYCTzhY5dUJA#D$*5r_!e`0f-$Xg3;*k z|Hpz=+(hN!iOx*n5T&GJpym|Qx7x5Lm-5Rdu73Njm569a3yA0DVENrkwAvffsv=^9 z-$zVDp{h~%@+AC2hs*W;mK`+j-lGcWJmWyUiPcm&F^i<$N=q>D##|E>2 z7;zAH?9op^h8>{y1IMi@)V6eqw^deswZMCun(iUi)X-33KbN)T)MPK*_w~}vXw8X% z@9SsFq)tV>&^Pvf{5seStLKt8&|y4>Bp9V6pNe!vTkeGLJN8}{7m~5|L)}QIt0NHt z=lu61wGdlQ#xIH`IJPAJTH#d1y$$LZb1#~WUvCa4CDVdOv02%_Mw){7mOjVk$d1G{ z-Qwpj&HGDSk@#7bCCt(8q{6o*x0>q85RcBQdFb+Vv@*^vG8mlky#Tg>a=O-y`21^D zYVUH5&;0ig-O%v<>0VELoAux?s+P(-CqryTRHRDpr6?v@=}zUoLFDGp;XC?gmN5Gd zmGU0urJVA6u&x&d-@B$c(!6EzW{Nc)OLLjqL!V#69c)}VURnzLZ^M6A1792k*hC<2`XR3FEznBuT|zsAuRX&uTq-#Xc+86rb&o0Do+eTiJ#hBD3) zG9u%KQC9EsnS%_@QY}VK#Xf|^e6=y?=<;M~S*qyLN6GfnJPYBmqa4enw=l%9@w7a6 zaO8#dz2hH%gXAw?y;X27KPYIuncs&{)oW*As`^;HSoPG~CCL5V6-KTtr!aKF0-bx0 zgHOiSrOOnULSa8!I8dxGZI6maw;n|656Fmp^%Y0s<^Q@QX6RB{O$NSeztOf__*$7h z9j@{^cgoDVVxk32dHb-ynms2z@*9rMj?1A%_X)7j!c$$oZ}BB%1GlKT~F23b-># z2N>aDh$AfG&(?B?O%2T2r3dfe5F$NW^^V#LW> z$t2LDVZNDvEYHY3-eS+}ApLHB#M~WgU-IQRZhbvViL&w|9vMV0^6Zw?GPQ*r>?Q+1 zuNLs;9w|ljl8Hxj_urbgseJG^p~@qE^^8orm8}`+q^TR=L5w!g;Uc2$x7TbvI{&yS zjNjjt7AsKV<9&3KslA-mSFu~mu!1F^J&u(^1k9$?#C5uuKT%9z^su5Js3z{~cGPfh z&$=O~CqtZFcLd^;Q5=Q`$9zEc_*=Q$SXL-}7Qa?I5%d^4C$T zxsq!!eG2zyY5>6#@^FaQ7SOmvV7BleH?cWV@6^Db@~9;nV=<=xSms^A&8hZ$Cnypw zsf<0Q{B;6?FJX6W;=jdjB*4{S)DDDN|FKNPXItK}I)sJb{#4AIqGOG6U8L3qXR>Tjqs?4`hY3Psa#ldOdqfcLkqd5>98| zCUt_jJf@;tQ|H4L=230@Hj~X9C5nvpJm6!4iz=A+=r>}tO+8rFL7clMv-Avbhtqyu z&nH}SZ8GA}^MUlges6q|RtK{P=|kQ>5yAn5&&WGbQoc{t_~1QjPpfK`lh!ubz!Bbw z<2scK9MLo|^V+qaDX)RXr@B^JmJy73w*b9x?I)QNNwk=feK-3&i4L#cNP3cNn2g(+ zW$GBV;R8+M0E&2r`M;yCV`cTX6uIB~YZu)oVH$Yy3h|`E2-QaTA4^NAE>r$5Rm__D zm|O__zu)^axvl~Vp1cna-5$YITA$FlSC;a( zv`UTM0pEQrZqbW>0SH-LVA#l*@_TOciOjxTxZLEax}eaO_5sc@fAuc%E#QwI3p+0l zim;Vv9`HRI(o|}Cj89I0-u*%23a6Rz{rxiLempX8dl18YE6GMVP0QqtLXykDS|x72 zpKo1AakN5S!e|#hxlwRN_mz_4gRWf`yXu#x<9GBT9z5zbe&hvhaq0e67WeYj^mw7u zeL0QVhoc2qMbe)@LAk_oz6~qfhrvN!NwNAj37z5hHiKBihqrK!z%)oTpN8A=V}Yq- z^GJ%&%fT4L-v(8>&X=2J`Xs47mAffnq_m~B<`h6+>xgIyOmdf6}ilSjOsEghmiWUtXTWL)`O!bC*C;oDj(-~Yq(k4)~(OlDPLCJ0^ zg+8jbl5ihgh~WAKh`c!A;eQWsqIYGE;FW_1VAbazFbY+0jg9Y~l?R9IpcrKsz6rWt ztkP4!8$Ax{`^RET7nvfwqg#-DvX$zGd|kLj6b+jljK6JuA|G*AK!EODQ@?Z<(L`+} zC%+zWaXE)FuRMtDPhnDi-%VD?&s*H6xo-5~NI(r~ARlAAUPUvEFjTdZhgOPuHMjfXnulDwv|k2a$5AqSW%_sH;|VC zd}|)|<|pfQ^88~d(@4}NGK0)y$gISzuJ=oRlgn0>jH$10@HD=;Z%6zEeE@M$nbg)F zytW*Fcl+RFW=VGTzNy3TWtGi9dQnBvnuvkI6w}6T&U4LF{%y3fa->BOA*oAJrGtNs!Nz&mwlap(nBN_A6=GGkd3-<8N7cj+h^PB37<%d3 z$e1?23|Q^2R=bVppW$XS)42l4Afj(s5HeQcx$ZpZf_O+@`$F%>tkPdbv$yfVifllB z?@uF_YwlGdTB{xATp!r#MX8eD|)YkWgd&9PMVH~Q4!Ax6FC z&S(Kq-lq@hJhT#1tv!ma@!$OUl{)k@hO9_TIM$BXM!*@Wk1x4gdUa8b8OM3yZsCi zXycL8rs#usikcRP?UYj(agm`IBsNDBYX{j`fk}EuV{NL|$ ziVeYSf6|T=0}hz~2e*w*&EoKDx7YvAy7liLMn3LUi=^OHkWdKZ)4J{X;rRL7hx?ts zY|87mMf|jMeys*y2Hs#G-z*K{D8?n!-t%VGNU2BkD~K!@uwlWf6}P~?BzDtu{`bdz z5k-idXG636?$=Jey2Q!jL|zST^q2^q%SuTm!jXaj+&HWXSFvD6(!-k3{~xaXd>xz6 zr7@PdV4AOVPc_tdK=)u5fkYSSWx8rl4h)npO!fvMY$F}!QEV>Yx~_MYv=KKSTvWO> zYu`t~%8j!R*hJp~z)D3(TKiWz3U4*bHVrqeOG&cqzu+cN*+@)?e5UCK1~J8L10I@V zTdLExJS41DjB@Zdz$^Ko))F<~N#qa0wUkQBF)D3z(xF{rNnewV1t{udBmO0a-AcBY zyXgXd0`#W;V|jNJ#BC(b3-+htXl6jZz<(>*NwK5`oUA=Om~!|QSkjLz-IwWQrftdnM0aXG7K}= z0J~9WM98m~#qR%=2zY}iIb3=?%R!#iilL{&v* z3-Ffzdm3RFV6X~oAWCR_3~Q3TJ1IUDDBey$uAXf5{+R0kLa&AvSQ%|$L{|E#w{y1! z>5AL#NC0PnzdxOa#^~VoH>7qe>X_%BC<46qt7Bk{+qz4H%%SgZQ}MvzU8svp_8N*j z=AfgOL%I2W8-9k?=^nx7knxAMX6;#U^ifC>_;3Kz(&G(7gKIeY)Na9T3041CR<)Yx ztpdHdW5kJ>{)>~F-UGJb@!r{CEx8m25;rau`;HREYnBOYe9wrttW25ZhHz6m#NNvL zehKYc*sBomJJA_Jf#|i{6~fNl^#QloZ}bb&MTR`&bo0zd93Izy7YyB4;V;*MaRj_e znQp6j760gZnDk?|FlEA5*IDd0YV_#CCq}~Q_H{t4xr{ZUWiF4bRWds^)a4uUSk|)Q zktmP@2Kj|92r^6kSdAbO7i-|ed1CzdR%mNzLQbCT`1(D*>BLd@?El5>f)B0tX$oou zjVMm5DU0=zD!gdO9V&lMmHy^UT{3OtH|c-u>qrcH+%?GBM5hvZ7$B;?$r!+96h{CFp?-q$ONbL)7da9 z?<_1+qbl-}Bs}j+2K;%yXc|&g^ULZO8`70^L8UH8@M`h=%~Ys)&Y1_nVL+~y7qalN zH5H47wOBcexZM0iyy9Ov!$qpdSzxW5xw<<%*FAd|b40g>+aIdq6mPr2!eLQUonuEnp5Z)P#NlE5aGsTe)N|-|Eh#*H4*$c*F z8JNQcK7a>6yB;R^Hc_kbTsBwv%k*TSJyPwt(OrJwD4nL zBX<4FbCcxTRK$}&xgPn1rCC&6#}JcNQM=RLnB?2i46(?d!;{G1aBR#pr*2KtBvC}a zAxBZ7zhV#yv>C--*x34$+QU3|)EaClQQPyPrh}2UwQBDNj<1Y!b7lettFep%=7lL$j%4XOEu*)!i`Xxj| z>g%;0VA=!D0O;4tl$V6B$GreeiNw){iN~^V1BA=HD@X!>RrL0PL07xV9#u_D2a;)F zkHHc8LX{$l_hz$vjPdj7R05L~Fr$#j=6`T#OIbi@_K)S*_^%|y!A5Ue0q|J-dKsRE zqMET|m~9isQ?7h&YJ?glDV1Y2foneK|B<=kk&BU;&aGa8F` z^xE4}A(-7h^B)Vav$knug!`^RmgR{Dv?(wtuaOakb@6#02IUIylf~30DRu2)Zjx=2 zJqvo5rFwZ+;g^n$zXbTHFm~kru~_cJsaRtv0L63y7*6c()<3|yN+E%FOvV%@9f+U=L`g3~eU^>sj78*6kss4rq~)yG~4PY{>r@;RpQ}0@U_QhvehLV9b7@SERAlHEu{VTZoq@frap4tuZrQ zbLEd!_$1a3#;OKcN1kr>KU3^Dx_2IyGOz2v{)t2^|7C!ajj}Tg%9UIoTB}qE^Zhnn!m(AgtIsC+mKaP=);QEmiS1# zas+NGi&X3rvnB!)3h)yiHM=AY+v17pxw9(E!kSH0?G20t_%|eK8U2RT3*4`OopQbe zcAnV_zM>*hq7nF#$gt~Mp03lr_q60!X#7slzD!O?Py(P*;#Opy0+9Q7Y0N}0uY6=N zr&)Q%WJ?)E`6#pm%4HDJ^CTY!pY|AJKoudCu=aCSU{ahdQwn&)jF+?{E2Y{`i33dj z^x!|1NoO3jabJXpjNgq%5^vJoKOr|q>_DeN-iYrZ+cf$a5V3zO*K`+3k^SAsU?B9x zndpM-Z$x|jV-ZHR0S&bsK)DC7>AVOhSjquXD8A>Noi^kKUH7fFU_>CLmR8-;)D1I(06A3K+#wuRU15s`ZKTUqy2ho zV`+OX_{_=5czJaLlbgJ-YFOz*`v@;xP6gbt|m+j+aA)hcnfcWMbS$zIlG^9pqU!GsROTcsLQNm+BQc(%` z?PowkAw5#HqQ%!*&N69{*nrNm+}?k zE9=UiU($d66q+C^g5|Vk(9IHRyd7*J4@f^=}vTf3_tTSoa zvS#qK%aw(-(dK4N?Xykg(66~4m!jI&acATu1ax}2UNpb*0@at$INJS$+|fmd?a{fg zLAR+Fo&!I2hQl6)ub&Rp_q6BkXwcH^lz}}AasK;lC`3~%QTp80Wd57McIEg%)iO>s z6IgYcLFYpZ$h8FUt&8AGMP6MDyl{3dd|iB~`5}3|FF>;ZE3_>=ba&g7Rsl&4G)2vO zY%-MGc7%^j(igwEPYhfh&ho{V)3$n@NPExJ{L@^Un$C$r2cyXfq?8s=4*A`LHWsqR@BZE@A_&N>$0mish&72jm$acFjA>RO1= zTUD{JUxIUNV3Em=43xKh3p_Srqkkkp&vstfw+2E6<(~GB9DSgL8c0*J%Y#4pyXJ zHl|qDFmghIZ_s05l3az4vi`E!V^kXMb?b zRrA726U~qcw|38;BNRiFT;m2@@QX@%g)*o0ROJqQb{BGfJLI%N0%S+nL53E+#=IIp zFr|jh$Jm(ZG-W_rE0aR*ca4AmlHrsP2jV+(7*eGeiFB4aZ@p7phb1h;W<1%qDdTyu z6~fhEAk*iW8BH%G+ooiLMhdVQGCk~{eY*be2mqA@uj>>FQ3WGdD-5hxATR}H#wO3( zH0#9hRjWUfa;>aw-&1q?y?t0k<*cun&3~@K_$l+XfoY}lw?R!!}%7hn|fQ! zjQ_53eg&2VLzj9@Ns;ZIL{;0F^}cm@aH;<#O;IO!F6Vnb+H4yjOHq+J4yJkuvRh`) zYEzS4c=aLA?f`IGwu9&PdCqG*Y7Mp<7R(cgOS*rxc{F*Wq#frPTUO4Hbn>lfyT z9}LdY1Y-a5hX2>NF@Oc1>mrL2OXUgSJ5`6K(Pxu%LL%;J2m**3@K;O2|9m!qP@bAr zrsAar{*yNw#92}HRmUa%FWhc9)D!ZH4yl9Vn5xOm1wEX!4GOYZV(kyZfrFmIHE_N$sB=fp7snWPA-ZGVAOEeNAna zus0`I5P~2ck)_!y0hboqXrEK|9*f@p-;$^{kAp~f`f4-VLg~)w4b#I>e_5+(%huIJ znqGxn*(X?F3ky^4kd=uHCpRyC;04)%|qg}l7vcz2F4kWpR^B;?%CBu=V z+y7n;7Yrca6R?DI{lC}|?hKJ-%m^-QMy`_F)yBAHG_-u#s@FLtd%auXyBhHw_nv?* zTMyd?4Q!J%YT%~U1?Uxi>gSK=1;DZoVaHnaAgY){R~k7PvN7nfWQ8O>2ML+?7Y79E zL=%N}JH%4vrI90SyOfow2(dL=e_%qUkf*aF$P+;Iok-ZjU-@-fj%_;*4`$*2$_uFQ zl?P4VEvC(v;X`-l7)0BVr?M$=U=wXQ&yo9uSc0u0F<$#R0n7Z|Dx73YO+BxF!}01a z5Es=~TzvYee>pHf)3sVjTGfKv=r^MT!!T|FTR0(1Ci;l(_ynT@aAoS2csY4>sq-5(Y)Qcy}2(vpm1LrkWcQZ|Ij z3-LbFOHuS%2uXm8Uiz1Q|JaIZZ(bkw3f^PE4-xOE=RCJA-ccOknc9px1Gdh;T3qKL z=6i_zp=<-0^9@5uTJ;pOh!!1b?^lFBrNX|gJ=vW&irWys%1}lmx7BS~5Kl|gG96z8 zu{$xpBZ+9T^kk z^tL?BF{!V)>$iL4GQ@ZQ$w%tvWe%l}RwEa!dIjH0bpDF`gPi-H({9I`iO!ls_dgb2 z>O_-%my7s+H|{=y$@}l}le^|M58DAb%)0)hfk+f$(>|V!O8DUF-lp#P8>2sh_G;an zZ{DztaTxN9-oz6#g0hnD-!>}zEqLkvGxr_S{nDcvAd4zmEBb#*+P2?{zs-GD8BWj< zMF~a*(VpJALO*=)XM3iwD&Sg|bih0N+ToLU&mR`Z4;l>69>!=uMfuwgPdd;m$^aQT zpVe|3V~9@x>q8?q5%u_ooi63=85&L!U@9T^-o0-a);SsTr91h?4Qq-pPB;1Fy({<3 z%!%Z~mbd`qR+POrk#YYq_LcL3hde4*v4c(#wy*=(2F_Qbq!CdHDHQ;BF!BVG5 zG#lARkQxbSmc5iZ&<9!f?BOVnwMM?FWWj7gwm69IlRH1tsja}&>F1h}R;NXmd~mz% z>EUMaa$P6?Q!&DcCnoVA*9|rH0M%ybyh8O=eYruYZED}yKKOdR(Os2k&=-IApF|LE z4^fAh_%JqQt}q|SsaCr^wh>)=zs!s4h>#uPK)o;Z&dt8XWTMPqPMH&kFXbX0kH2U< z?lnHmSGgS3VHw?8IKtsZDfJY6rOWRl-utZS`yN|wIvH~=#Bx|gJoMd-0MLxqBHw`r z2i&hpbEEC0+Lq zIw5TaY~r@nYAMz90i7xlACdG(qajN{88*ZE<$^f>t0sDim3sz-`LDOq``{dvbqHm% zT52jWw4%CUVG{1SuC@U#blpQ=3{c+FXmZ{b7N6q!ODKGDF~2hQ+vp0qm;GLT%SIJ7 zlspUUS<7yPYmQ=Ss7@~iMWrI_9`uQyWDdPvbekK#I-%N^A1qj&-&|+>bS(b%-=<0m zYm!x;bY`Gq&7NH09kGB_I!YTwX(!V$fE3acc<7Nx+HfLsl&SKGJRfHd0P;)n$1ciaxPs+4j1D~Db87I*tA)G2~>Z_BCyLQr9#Eu|WU;>y{lxrIBk(rGuM*D>k(; z?9)&{XFp`qWqbDcK{0?;!(OekGclc4Un3`n#*q|nYY*veiav5qiXPvQR9T?{3$>rbGaOf5!sSr%Fk%d zONcFqMV1*qANe*IqFJEzVsAUV*)lfproS|s{q+U0@&KFsU%O0?zM7ij`ND_QwxO@@ z*;Wpq^~1}8>mnuPkl{KLg_MqL4Cbz^#iZpK=klJD1=?QHZ}N!RL0FR20)&1eH3RnL z%U=Izv*{=!{|zKk9{W;ligmUna74Peu(!NFAOBq60&Q)B7)%eTW&N#`{NW6eVUjlA za&op~R9CfwF0=l$>F3WIT|5`q_ER+wp*WMy1$Bg#}ZPF z&*YSWOp|kV9!HTyG>290NMoC^i8BVx`yM$0;2(q=lmb+CYXhbRD{*(yvKk)T6i{&^ zsYEB|Gl6X$G9H6Z|1IHK$L9^$PVP-LGWF4a2@)#L-CRV*emW(*4|Ek-K1j=S%67)Q zPNJym|6{q;XcElo1n>|8mJGX8??L8N&MXPJh!i8;?iwstk7>*c>l{W=>DEYK%S|YK zWo5`1%b|7Qh3A6d6XY)t0v?kJc59etEy&>#yo9`C+Y+Pw_b zHDiv0$rufGEj{as+5f&ZzBw5~15%iXtky}45vED%(xN+a%Xda{V9Q-TP&D!ArQMll zomK)t%T(Ii{hNXyX8gRjF`Odqz zU8g{a`SvdV837>|dxFXrre&_Tz5TsO95$6n&qi8)PrsFUjGTXyrNjUf_I&7+bwNRsIpiIFgcK2Y%Tjx}~`h7_h8`2s>~92*_3*M;ZvR-}Ir>91jfv$r$Y_?06lgZu)c{cLwQ%i6Vec zs`%PtoNaGf3F>u3X&);rT@NcOJ9jpGzC<21h##h>^o$F@D z8a?8_Wv$%HSPICMA)eUe-1Z#y+(4fP4lz4tKaXSR#FS)?;DSWN!1$6q>K@9nEQZ~f zEuu6go3_T}2SiKvQOaHTYte=3{4V9_iMrL02BHU>tF1WsW@~ccWJ_m`57XN4&QeAa zYOoP=ivEBsH>2jp+1*FP#%RB8i)9rN6U(GvUNK@+L|%foLWwTdp2fRdWomI9i8>v6 z`S%7#{=k983+Y$j?PfAlqKScx@1&0cCU=3hkguJNoSzG?)J7`K@2lv^m^`;(-tpR6 z^<P0vLKzEBp4knksGFsI$^5cpGSSfX?l;~K?|X!#gfmi9G)Yn& zMlOw8spH#c_k?}kko(e(yS43)qFX}0nb$?-iI?7Gk}?Cu;t^Qdjblw$#A$M~CFm{v zO^?&9{QM5JjM7W~<9!HQXs(-}0Vw2+wxDI=50mIT%sHES;C8Nq_t=rLp%YIErA=BrgE?m7VvQVnQxJl{6J9r6(d5J|E>|A@H0{qUni z_Ee}e{Pz;@s(jV4!5bnQ8iIC_L}7}(ivP4?BL)pepVaxKnzxn~e(jG#SC7O;yadIB zh$&K1-^)v7i&>{sE3w+IWV-)46&oL!-TaRQ-+#q6K*OxAwYomoD#LUtzQwHWV9g3# z-QQ_SeHaS%WN(GIHHP1ime=_4KJ30%U{;OEi_@%dp3c{ee@Hd7Gfy7 zCZo89dZ5skT5h?euidTRqnsHb^7Z$5MAlx1&jevJbgmbw=Zxs`zS8cgJk{_b^o_yn zVDkori(G+r@h@FnUgO){=t<`mIrAvv@WlQvNLHxiP^{T6M-w=)k`rk7=B_I|0tY4% z-vn$5w~xMeP_ogTEE!tda@>M%BV3t-vurzR90A**l0^Eddenp`8pQ;D5M@wxky)SzHKM5@2usa0M&h(lbn(?kB+(;L%;q1?DLS8QbRCnQ;N6ijj zB{|jJXfu2D3S{LRe%s{HtT4-d#NzIGFqA5q=*aaN z9Yf>i<~2XqMbm}8n*HU&(JzlkvC&b8Yq7zA)y%~v4H+3NCEx41{3I$bMLRj>VePVgc0}jgG$rf<=#AHYHDibo>b-}#l4lv(sGfSnwpZiCz*SaTXT>T zH;Q|p;6RY^{O66tpdrD<^W@nghK*Rm$97b(vEHJsKH(4_=-J1lYsm7IZKw; zltlRvn8s${dHn+bBQ!NVWwXhMUtJaPALFa2Ur%7Y+m83~C>HjM9%fTG2Q5JJ@j6*T z=FczC0|i?%|I%i&3Jw=#h z6r$xA_rS|`jzY1MLbhVDM=s98*KhJI(nd?tADEiEYKvy8YFm;c_-+>#h(Nv`gEA5V z($rVdt`!Ps1i#pl${4BH)^BrR{>PbM)TytQ{Q!aj9}WOasH25_tjtCL@DnHH z6>e@QE*cjg)DtAWptEiJtnTGyjY;j~$ro%b=>xTi=3fEo=j3R_#(i?ny%xnI#q9Qj zJMDj~ZRkXn(K0@Tv48!B6~brpgn4mo)T=u*K106-9Rp26f|Ey+Oii&BAr8Y(_>X0K z^3YqeeBVbkxS#Q*yYXL4ZgFlLm=Qw?tR)Z-0~W z9zni3_}^33JiIeQA4W#4+0Jcx+&)+u7{&g|Z{n)vxA7G6MC3#}$Ug za@|ky`wJJuULaJzFM#=n#_+X7CwqNYcNk3RFLnLtfuR-x_PyLez^r~;#?nnzM+#p3 zck)YzmL9vT0earEr33}uN>umXd41p&@v3&uiD#KRx=oT20eo5V-@{ITTL+e;dJXeb zwW`FAUp`BzyE?__yQGl zdMD~#Q+@aJ%`wHRSVz0`kUB!_4ZneF-rx*^{ZaAgQ@`xwT?;i6zj%ql*)UPe6p8dm5C^H7C>0T2HYuD`586f;wOyLWfr8JE6AwGgU_E&ywtr zWRYQwqu0pCme`#mV*cFb$be$b^X=@0qhnN72_mm=>shEcjN(-^KGs(yJgEqkd4<~C z{!2vgMh?n5a3}Zrhy2HqW}+Ucq)&!Xpka%9GtdsS$A{%vUuqwqyqALnA!EqNwmYvZ zmm4bYxAD(xg0I$;6kSAD9yDArp^p)HGJW+whlgg`7;&8F!< z$phT(0X;zqZYhKfIR0_f+kN2J!_BGcD_hfhu*zc+a&UavFa}IIM5g~wXk-9!60sv5 z#e8}_)Ryb&8F2}Ih7<#tM5{&Ko7OK3w36qw$iJ*;zq7tV?m8Q9J?vb)Xt-$ zPmcDHU8d8no$5d?)=?Pn%yvslad0pY=@ixRf0$#=B>HcTw$c%N7k!hn0>|=PF+OMc z3?4i+JUKF|_gkF}$-ugs5v-)WtRL}Yo?L*xGG%)-4f!N23?>5))>ZcnNR?hpnShB>XO-Nqr zeb=AsFz@@T8U0Qm8VF_h)o`g|50xiy*UGf3b60zGHLBmK zV*Zz{1QvAH7B!w!|4`BUt51c!vm$(qsQie~b~>1vMg;Fx>@VG`PD5$@Rl0+xYb_>4aR<>E+QBvsE?6J=F zkk_>Bo9ic&@~=CdaSvmhq^_iHK+fyvDu35`5jhCIxUy3-m%6@sSb4Cd^u}sDD{_hK zH&gA(EkTPvfsoN3@)=2Or;8XmD1&3__k5tov$CZ^YVvRUy&se92lBlq8Rd#=EsS*S zbH$M60*4f8J0K2P{K^DD*%6NJ4rr2eBSyHR%`pJHqzvryAm*20;Nj5L4v*T`7pHN| z>@t38O5Gy2q@x-4l7Zo&us9$#U8h_AiXK6)1w+0uV#_{L-LV@;ujdqGKUtCqt>4)~ zlXBXmVGshK)InHjJ8299BUcO?RbE;RlA+1qAkykn@ir=Q3w{twc)L;MW6)JiDduq0 z6@5H(t+_&5Eub)EPiW#0=nxk`3V5rS-&;+hBA_^{Tn8MF{wO4OzyxPmvJDz{1@>Lq zqm4FgqDMHGlE!u%gS+&ixGtO^6a8p~t=sQyPG?l=W`B4nBjw06%2CX^U^b*+!5Q#( zJ3Y{3fBG+HP5eIl_$xohr;BAaubLlC*u>ps`R5zbgK?I~6R!xLj`|(S{vq5mbf(~F zgh$@C#z-+#{o11)gY|73uTV&pZ`#ElIUq+*eA6+s9;v_O{@`9$cSrN;YHi_3plK6f zA{4|v9W1;%`#PHM6bew8%%EKm@%%CE1GIikbe((s#UK0qn11!8nA~>0Z3_P}d%}M# zye$#LvS(3G>YGN7U>9+pCsPVCc^w`N_w?R4z^a133Q|W}z%&zzj`_GIxS%ta(lIP2 zkN+b!Xf^PcYvZ3q^03L3(D8x0rC^m1$55p>H;Te-fPMQ!a#}!s+ zRAyUZ)%FtL{~R8CN5#|maj%I(>qDZ?g=WHDNtmU4^TLd6Mp=W;L~0omf9yjAD0&4; z^ZF}ozfyRg-xo*+`mIge{w>(_0e-TCIM5AtiRK=c4iLLK@4j+M*6;JZ&)#!PEjFNR z2EkuS?bVo;2Agmt4`GLtFHFYsI8^cGNQq5^ z->J+mk#{Q7x0<_;9F(W7HUh@_T-*g$zaA+~&_R@v!VOFH!nc+8 zeSDS};d-*RmqW_S#IM8Gt2HS2-UNBuU11pQ-vg6-pb>O;5v$QY^zgA93HT9-wHsp6T($! zPdrlG>d5Lr@96q0A^65v1KZ&frT)+A_q6RKPyLRHibC3M>F=n$jAA3nb%ddDAi6^c z;$0+Y3s-$qSFtR|Y1@XVo7}<}RyR_`$6Yg(-xEw*xVRsze(YtrQoGcIio0#2Kj<^l zkS1JUfPV38n$=- zJ7~IZo3gM(MwSLJ6fvaGJ*J4eM|E$xBF>BiQYnhJ5^rVFKyg~G%h(Qv)1qmj>&VeL zo0eLen+@@iyKBmPm(hKRUHm6NeiL$e7Qy9~*_IGY!oc#r?v|(imhl>X#a?s7$1Iv` zK`m7l!D!Fvm*A}P>h%el;+&?rkM|BB|C%^*0?zL&u8fo^Y<46D&Km%k#^G;mS&mTS zgg3k@>FijlsC90c zMgF4xd$5UCr9;<1iQqc+*vMOyCg_01HbHoh?emPCJ(u-(Xi`GgzAv=n&;HyiDZhdN zFPd;6SgGR=Qrcmb@Rx_oPWd9b-1!Re`z_)wRw-uwTU3y^CMfhIz=#hX3kHfRh4za0 zyuQ7mW7NKu%0tG-7PyB{{@)231j|A@U>G#f#fS@!5DA}=WT%A#?R^|dtBz8Hx2mJo zCOl0Hn+H?IjY;4xGwmx?r9QL&qd3xk0cg8o!0_sW(KC&%_)qEV`OJk!fmdbUnhBl&OdPt71I z#^KA3oi|zBdOGR@@$dg)EA(~^fgSBl(Ufo*n*6fd)E3j zw}F`hIp)JH5LuM;e$da=oiZ;@0R(jjiuicYiJt*pfLxoA$bIRF0Ic!#GVxSPs-|wq z1#M^h6}bch2k+6=5yZn0Uz*wwPWYW(#w$D`ZB(=3a3ReMDQ1BQH-C7oVeYR8R0 zPqG_B2eu|We))_Mj7Y>T$;=N)Ecq#_A9}0!w6t_x+G*#4`xOz@ zHR@h_3W02+hZUGvR&v^Ccvy&2(MFJ&k!R7KOM~t!n~b`{;Vb9ZwU3sog5Tji&+>T{ zz69_G4o$0qsFTAI2@?ab>NYj6cd#J6qd7sfQEIoK2mlxr#t+d`JYAnVFg^kK)7ex1 ztji#~E>6@jJ_Z!C%$B+Vo2Vy-VwF7Adi1BnHB(nh-d8Gr)&KGEU3`(JZxYIwDyT9MKmu)S0PgV~zObL?=8$d)#_woaR)#m%&M> zo931C->|?)>6sIWr|o)ze^SP1IO1gp53?h%O)@aOzrH@BxeSZkMiPx9pkV?61Kh0D zZ8#F@U*wZauKqybZvb0hde$L$@)(n2ATqWD`?eA#!Q5aLHZ8|@k02CE%UjTk-@Mxw zeYm((pQPg4;pCzOiVpKa8D3-WYDd$=e0I*)BL83aZ=~s+rkIB!&BkyA5jH@I?g_jT zc10(Dqwb#dRC{)DMRM1^(Y@7AM`Cr~6JA%0-bo)wyvt?oe=1*ILCz7{)8i8S%_P+^ zu1IG`ekc9HJF5bopowO*aauGeF@;ImoqM~PU_29(d6Rg0Z+*NBzMEKWTmxkAulUMWNk6Dt^P7Y6w z%1e6ue&CzQKrQTU+bU^Y{Ku&9_~1~>B3JBZi$l@E8M`>CrvU-%L;Q-lJX&hNy39@K z@umv25ZOmtP|HH(TKuIzgwgmdOXg-^Jb4eGl2z@cS2eV>j1?~bNmVzlfFz~khoqLp z8cR7~LanJ~%B)FB4KrH42CzP?2<<_*8{*%eaqX7s2|eEx53)^2`Eyt^;?#-6&J~4T zk9{0JMFg*uo-N;BY{b9+m}iy}BoFjc3I@olUiK z+_S2pCMqbGxa(>54+Kd-Oa^qJM>K>N1xn10l&540T(Y!CeqB?|!OUf~6hR+VHf@tl ziK#8+d3e2?_#(j>KO~K6!;~a}>GJCxm*DIGgUJ>1>Bm8U0S6O$USVIqNAHoS&mO^1 zzbM=c`stlQ1pqb%G=Q_soj#V&Z4UKlDVi`tE1DzLjF&ca&B{zO!4zI( zX&FQ#17da$O)mc4)UU%?&KvZWIja{-tyZ*Ct484vB7+_=3O(}-zG!f(e$6<1+Y>dr z9W@Z`B#1otb3chX;b7D`G8p))MsBN>&DHF*#D6T;;8baN-$J5G3Dl7L@C$nI1k;7A zg+((3f}=4;<8seVpncqn4&5A3e@j~4>KXccFdGBfj&@_e+`A0940V*N8hbvL@ByFU zT8kX6A74r(1ANEF6}{iii`mn^OGA6xXZPYVm1BzCE@ws;6wd0q7Eec;r`_X|5{%_d zXiwpr{l=wT3$av>*%?`Ka1n1v1aSr@EZu)yAV%YA@odP@AAH~U=pWO6uY^vj+6zf4 z`-9N_nbhqfU9UPQ)FV_izNb#)@q=UO8TWuql+~*LG1{z0uS(R_%?0(C@s;z*I8)Ny z*(oW{GNS7WYv081MpI-INsp|QAVOTIeWQHJwukYFkn{X?*e_1T9~y$}1!PzQPM4i` z`;|&7NFeQ{KRHnQS)q%H_O=rnfv+0)tV+K*#@S`3$I>MVCeAhQYS8Q|e37FQ`y63yJ2! z;H%#@z^+=D5^YvhaCK3a>B%a9sOKt$SjF7FU)kAkuvW>s>=;E9FmqvijlBH`7xD~? zqzG6gQJgH@!%d+%IRJls&oM&MG^Yr)k=VB^onEws@n!s!tqb>RahR6@H#YrIbx6-bVbEd@3V%G8cIyRPeekVk_`s(j8 z?&*1k2iKq~s zimse>F_@MA3D2ypQKk1c$Nu0Pp295vZi{yOr*^`F`hN5Z=ENAdI@NLYoYQriS{1$Y z)LNU-5?CRlJmK7Ap>{b8tC<*<$sf>y5Kx)#$F~YBPQDezQ?qudtgS8-NIP;y8r%#q ziyQ*|%I;o|-fhvxU&<%$y&n}pn>E;{ue=j^yqXw{F$p_Fsc^*?>8WHfTbjR3+*B`1 z&TMAZMxb z)J+>ioChp}K_5I9Mn~~W=m>uS7n|sFxaQy6^fD*r1$QZxUgP^&%s2JofK4aroVlxD zotFn@0UicB(#X5h;x8!tsXL-yOoPl#0+A5}_oc6?fn~;O^omubZE*GL0Y4fnxG{!U znFoAduyM@aK2nibVXh=o(j0tKdSV;>tL8DX4wirf%cU150m33F!S37Ybxd7q)pO@v zpwtkcC+$o9?zQD*9z_7BaP}S_1(k;i7|8{d0S2o}NC!wo#7*G$vXAL6e}axKya9Ou zTS^?GGCd!y6Af4tIs-Taqu~HOwWnV{-li37xv;6zDfaz+nZIg3sF-U!a#Hc@ll7Qf(!=ID(u#=0thB zSVME}p7Us`%PiO2cDH!2az*9Um8eR2g%nfHJ0smawWc4+Al0o*E5_v|K8wyjUzC!A z>MbigwZP9%J4Ph2gD(D+$TJhyw2V5NMh%5$A|KviAl~xmH&_VhgysylFil z{NLjGWFr-_1E5%0FtqvVrMlS}$#Q~kDGxC81}qS?=PZ)9=CM=KD&q z3THak4Wy0HFKKTvOYzt>L>%*0?Lxg$S28ROua~UHJm5@m9HVIkX9KQEF1XlaFTm%( z)iY%?<+f9nvq%2TXU6lsD7zZ8S+&Se(E|&Kb}6Gw#{@CJRiU%(jt6m@sW7f|-f7>d zsWBw=AKKebHzI2fRd$A!^@!^`&CA;Zan?r~P*c%MM(@H4ajBY-H%OZh@vQ}sLW)413<@38dDQNd zz-822rNw1o^XZUlb0l1jVpZaSn<6unCi9wL$ugG9Mwf~P#GgM=$&57>Nc0(xx3rMz zVNb=ieM0wbCFo6zw1-PmvWw}8B+tZ(f;pwyqxbI~<@2g)0zt#)ML9O0n=)qP1tRF< z(FIs7`}-!Pp`(!l@eC9-iH1CK*j@#eF-7DFB?J#8h?v(y9gIxAbSl1zs*Pz_Or#3= zS(6NI#aF#vZ+&6Mst2%=)WS)mc*&D)6X7jdrYR)j=ofPe7++tarYtf)P;f}5k_qtD z>?K}s7$8PhwA=@U8nld8h;}j*-92_miSw1VEHd$;q;4;HM3rG2djC| zzINFdpsh1KyTHJ_*9N3WzrX!&=y{&FPEc5CCYY$=DP~Jk3g1*yl6o0_{87}^E* z6XB#>eP@+VwZ>Xr;Sao=zUzh7?6P+04j?uNA6<@7c z&pk#dY?T(F^|F^o8v7xusDZxHsiO0>&kB%s4`gvk1O+jGD4YIg`m|?yBGgEJ3Vh=Rn6B$5LOvvs z0Pd;D`oyL}F>=8X46ri(fAi|6k_#4ZPbLG`WtFMJ1Z3t+IOPm{a3_~h%zyts7SZkd z5LzIZZfuPpBU?@%YqN}4ZNA3QjlIigLE-IS0P|Xmr?u)Iq>a2a>PRRSvdZNJum@k2f*Z)fpg&)05%5gWuVhGqJK(*u~TVs z^iyDZ5>^F>-E&=y6b44*DKbDF=>sgF{si28hkzkL*)QdG0zAek2PkcD9WYm91{5f6 z`izE7;OB{InoIb@2w}D83eeY4F7cfwzTmys5$9^)YCi=&ACk(8QI1BoA(^K^%twbq z0_14QhY~yaO(w^?^Ak~Oai%F${>}18X}V4Zx8BGj%dH}l8?nSMjGvLWwl0^>jNJhp z437dfO4Cx`iN^%}<{mT@K4rdx4m+nkonF!ija zhOSF8FIpSD4is0pwIQDAgtN;a{6xMuvjMoqU6X{EUifuGZBGOA zUKgBh9CCD5f%%BBM@QHu`WWw776DdKhpnJq+xZc<^)U+@J#$9(8>R2zHl=qoYA6^+ zmC~9|xG(7j!l!i}apD95bf3@W9jB!s_RxH@#be_RI2jpQvdy9BvwkRo$RfoLFVq8k#;#I^?xh_i0&~4c+$Cj1wcp(5peIRuh`~ z=Mstr0s=lRz2^>`vOB$T4lY?1hPNCmUunp3TZ-nA-JQA^t0tOBEyJ4^Vw-7cxBVXr%fUf7js4BL0DdyfN2`SiRzrN_DcDm9c zjMR>jt42Z^Xb;D9E?ZhAI%VQl(|DI(wDWECPWwib8QK_g&q;PmNCiX$*5Qb2N)1tb z`5WfGajht>2$`@7Pbe+|k&7coS7)Bvr)%U@|6ByK05)8;gMcm7U>41Y@H80IUS%u* zGsuKwSo>>=`8hhclXyDSO$zu`W^2piIj<@ccgcMVokZIsxeLLUx*f$6HL^uI)0DaW ze3R#I^nncGR8}NCo)<4otdt`yXBaRFm+9S}m#cq}3JxOIah0*SPm5?SCJ(et8M{|o zp>JK=+|~?}e^!PC63Tj6SXh6e1e(VR$51)S)J)}`B}lFnvKp6oR2+_`JXUPw5-6S7 zG?0pPg>6V0!Ka1=5;&G7G!4XxfQ7NYU@VMz4h(k7-vi_vWga06exKD8Q{dXt6B57^ zubuS=^JK#IfjAH_P}oSUO7M7asau~J70IJq<(T% zg)-iN_1di6z{^GEwSEv&2c<+p(K++F7p~ONtfKcSjwa5e)%gB2WTi>>LL)UIQzrzs z&)V!C*kN@Up;PN+ogoQ#4tybFR*X>l6@RIQfUx43VV!je)&a~A#a#P#H8hL*KCZ!Q z-MiBHP|LIXTHUADSq@tjtwLPF&rt@Pl0s!gXfUYDJN;?djPBs7^(V%Hnw6dbLV3vb$HhG1S>{RRuSopKCkr^Jcn ztgemjD%}3i&wG#(9~E`{lR(pgjzRwL8ALHz#Ds)Ygpi`^?_F>_(T5C|ff{ z;5g_{Np-+aMf2E{ZzvP z2edfDeu5&-lTMQkf4p8?1ENq-JjAyz@Bb2Y8UHCeuoO4$s~}jAxl@!XjE94B-sW*N5ED0xLm8OzLxk#5SX9(8tq>Vx6hfL~{Dq@n>8vLS*N1P(@JjMVB?>k94Toa0 zzP`MzccI&%E}0NWK;>fo6i8{+!hKvHQof~sy~Jj#SZ6)k_2ZGRuV)J zqRIE92Ym-443u_(Tu~FyKko4BaJNfrAiH{+S5|0p2$9G6nrEy&OX`hfNp=2%g6I#t z16&RV24Z`wp2?fkw(^erf~S&-hsG7!P|K75SSrl5R1_yPVL=2|=+|0Cx!uTGBhYy}x8FgObanA$3P9gAIhamd(AIh)||xk8N|R0P+-(B`xBH8JKBh zU4nIG`z`Gj*JsM+`n>Qxr_vLOc)-rO0cABIHh(@HUOQsz*6(_Xz&AS-YT1M@G4Q|@SwGdQWT zvalhUFXy(ra$vD9%juuI1PA>cs4A!i5;G1T>t&|&JIaxe&tBjWJjmVoKJdPX6(XwR zS+uf!lF_`KoN|!UJ&V%C@1+I?HkUnAPC)0^& zf&oOLB_m>e&uSc8E&mnn1c^5Zt+A8>q#gAXtcwTQ7u^kFNL)HyU`h*woET}p9+%bG zvSw|Ku%Kzp@xou4eoACFDg(C1Bu+YXr5Oj{3fj$OTc|g?f0+RPbS;a9B}0K%UzS%Z z(Ha1IQ1Hn!DOM7gH~@HRxxRyj&MLKE3-6>_oX@bab1M$N?^~t;4=uL#5a2CVoj<{v z%Em}5OK(4O0YXxI{ReYW(YL4zYsK@MYbwL??6vl{on8&5h<}*{A~gIykd#V`cX1~d z%Bcjk;k%&|7}kz{ypbi$@_%AfPXXn3dB>n!%R@j6Wz3{911^uO-5s}Im0fk3#~l1{ z_l?T*I{sTcpfiqk))1R)fkx!b4*rAy`4MYKmz}^Ug)YO&FxYJM*2Ivz@U?L{x`8lK zsG=)<)M%xmu5*oNSb4e9&y3DNJd5oz<-P9&3%G(5bURkzNfFd{zU<`prx(TIFPQR1 zP3f=)NgBrWTFGyy%XP^ZvIPb+2i(g%__@l#Gne(wxC98lwrksP5ijoNTEj~jX6xZm z{;0N`P;rLHk8kFA?(WCX)iOP7H)a~tiRK7@d6K%%E@ zOTDo40B2KH$9slKHHVNDcWGy_-OaKS^nrF7_~+i+WmQ<*0w4Vbh#p!OE;T)UtuSO-Dn z0kN%Wd5^>PQiYuU)3XIFQLC*D;qma_z8V|{uC>8dou(gV5D9cUr~K*PV+&iH=YQA- zX_-W@tk5o=sE|L991!ol4&gDG0zjRO?6_Cs+b6)(-u>#8g!r2>x0sg4g%Z1xn7%N7 z3ypC;*m+sH-x2%?pfe^->Gkm2;{of0l%*_*i$$HF%S<^WqsXF{P`z|SOw*aMWwuF;u64ke%zuN4*FHEJ!%Pi`MGK zOc?+evW->C3l}EZdv|+i-*O`;s+~UO#W2ARXVLBK?Crok>+k_?3xH`2w`P9+U7-fw zw_@rKjg(|51(*Q=>IiD)BpP5Iyl0Iovr>L*16`wI6Xq@Wx{}<-QOH0T)S0a|$wDtt zrupl7Vrvz$r(qWSo}cZDsT^I*)=b(-^viExw+v111jTsMwTannIdUQmsYV8h?aI{3 zu5ZiYyu6_Mj$ZOWDyzr0fJo!e-LQt)B6-I8w=t8+@(hbWt!) zw<>y45BAHWZgTnKt22^!K?MKBAmO7GVR^s>_-!pMLF38Wid}-;tE8&oF>LW7kk`Ql zEbnS`f@dVxHk^pq<^&?yGPtEy`yo4nWg+&7zm$n4_kMEZ__F5NT{30o`q)unS!YZe zKrNL<5a#xYl+1<KF{?NNeUpaWQlpAa;<$SsG$gf*RpK=fnD^UnGVxW@ZGZVVK0OIJLsT8|MX~|$ z%JVv1fJy@;bJTvjEhZmRXTuZSwk&yd{muO|In%w4NZXC3+o%}DGC-6NOn6OrqJRBq zCD-*pF1)K+t-5bqr{R%IndL82I~yDwYZ+m6nMip2@b*!kZNgz(>#VKgX3>fECwDKS zC99pyCHQ;qyiKyZa&A3)7#Jf3dQC(V1tXQ_&qDUhgS$_)Y1i7OI%A$0qZJMZmATV| zFJ_-F?)HC_p+9t7QnY$99$ccbv#eHb^2R6S@xA4RoJVH&)vj0a^R~$nm6Mi-RCY3Z zkT5vx+uK|FMH6<#nt`|4?0~S6ms&a<)uxrf28HA0?Q*w)M>oVvb=4%&2OIw?42#t@ z{EI?RxI$Gmd)oLGvc~H5Le$cXqkDQLoc8>a=i!HWC)2yq>~4cMf5zVx*+Yrc_~d2Ek1%e*lprt-e}@6BRE<>zmF;n>|GDO z;(0}*e>uz4Oz}zHRk>Sy(g|BnoTEeI6FVBx+ZKAqGh1`FRrs|FU;*wT`aWLxhp-1y z9$$7_l^hFIL+23v8;tW#zt%rgKrU01_quG$mFv6}v7B`rJY`ltg7p{8aU7buXf}8^hR*e&(TXkvB=m~ zeV`s@wjmD;^o97DJ__2~+{QT#(CzZui9t(ByHSltY-W~j%<(6YTi7#q`8JbTA0JG% zM0Ms|t7{?&m8V!2?rB{K3UMtaK%UYah~E~#6j-Ud@@Pa39)D|cx5YEbWR>0rXaKnB z;$s1TT_3(<5=Y=s0l7bLGO=cve$BY+;oFom8owTZSAcT5HM6Q*`zvt)2jwN)1o^N8N zbR6UM^;5pSym^$F8Bs(<4k^0tM_I|tUNT?mkzCQg)%HVt>`}GAD~pd-?t=fZ9BtLG zD!JSMFqPWL+QcPqRv@ny*cLbFu=z?{N3$fY(!dSm&o1tW7XL zf4maeU#CMy4maq_&wM6E;__x&tfYDezG3GUPWb_P(K9(DJ2_$3PtP%oBd+j(0_$Gy zE#LzkZ4=}!ySG8;*Wg`u@))k4UV@VlbgAy4f&zf=%K>M^3(X$FlSuK{4rt-A(h-_| z%@?3aY8H~`NWhgjxn)Zs?{c!y!duqb+5kvQZx}+(8pVzR{KMhH8W-elstg^qe+x+h zP9YYYsfk%u!pua<21gAtWlWY4G`ESv75*9|3)~5GiW1i$buJFi&S?|?E8cqYZ}eL5 zsEu+Z`Ap^Ab5^WxA+q$BF$4%#ZM~35o;Mt5kw%b$LI9faE<9Z1^qxQ&0Qo05qriMz zcSfS7`yJr3<<=oK=E(~t~t#U-kmsTGJoo&b|aTst*pKDDBJ$OA=jbFHHp!2f9k6#5)GQ%6^*~kt5Nl5-v@J0PU5JOO;;Elg@A)}_^-8HD>W*I z3@l*(5~;T?PvZ-XbjYx@;_3N5%xa%P?3jDq!)|DkK?S?|u?A#n7)I%5oYguDbd*Mp z3Zze6Ibx)DCyxF9vEkKO_`?$9Cb;7x56!!<-(@HhtNq?`0=#d zZtp=-E96)e&@M8cXy&VieSqv@C&1NcdWKbZ5A%3RpZV~ARm>oFAP7xsM3qMVV;cgg zV(*5L3x0v99PpkpMR*egk6?aD_zCZVFCm%9m@lyV5mp<}EmV};3cMZ6ya_g*srZgz z)JC^GAFqJp-NO7JPs5etfYW>zL;>WmaLZc8?da;kw)23DG*g%zpH6Z9k0rl)4ZcbOLzD3K($-Bq-*G!)JI3R9}ivT955uK}Z@NA3u z#vWXg)HG8xa+ov~{BqloxYk-kDbla>3Bb+p#QWy z0c<;y>Sk_*INFySR#(8HU9#LYjq@mDoql=W*~`KNK^VgR?P{?PsDXVp;Idwm!!53agwkhht2=k1O=`HP7eF1*ou!x$7N^I{M_+P*Sr z>5KNeaUlB>Fkv}B@Ng}g5a&WR<8+ux``NWM$!xuW5t6T}Qm4Wzx6Y#A`4W1$JtLFYC%)hlr)-cUbn0tk98Pm=5gmy{pD?A$Ya(Nl@GGxeG`^rdR zOB5bW$d=av5ZJ>SMv^u!DqhJ=1kSge^lQV?S7PW}gs{t&nkDNQ|KGbl z2kD>auz<=fERTxSHG2n#N3YVX)LfnV#hT!WAnpKgT$^&s#L+nhq5U5bNb{*HTs%{e zMdGa?l((JLP8HC1ovI5J4z4ovmh@zLkT{2}LajRdOyI#TE{o2UEp73Et_2Z>18ES>-wishAmEx(^zmIT6HKQ zfyU3An1RG-3V42}#BRP`(tqLVyZFVv>Se;)UM+SLC_WgU#6DlKS2M&OUGdcmvQTf@ z(?DwAw=RwRQ$$x#_YU4_FdV7ShqqVuZhgRYWuF^(tdhLV?=dU6d!YR{%ZK{Ex#QY( zf{r`smbGHU75x;Wnw0Q#UP)QVY2Guh&aR{Eu>-{Ipl9^bA?iex;?QYs%pWy6wC^{O zA+2TVfm7HB<4eEx@}7SyLNYe&_@x7-=|xF)`8;$2AiwvG!wjMBS^jm)lD#E@*pFTD zqVD$&T$=ZQo&Q`@8R95b9|)`+zV*#sHu(CgYwn?3yNn!@6D(w7J={z<<|}}ZpK$l$ z{{riAU^RJ@} zjF)aZSu3_q;ACt2bNwvnxbIYRgWbi_m)ZI?R`^4DrMFLy(rCNnrBDRX7TwdsF`0qi zK9I46a~OCQOdGVOPE5VKa$c>{ZEktZ@khaUrL8A-FKlpdSaokG@4*}G9V`*C=yOzF zPOsfRCL|C;TBJ(rWBsT4#sau66zi$lxd&gkL5{rNtAnsT39t7UCb@nnr$d*@hQv<5 z%A+SD*Q2HmMdk!KcBSh7i46|@^J5m3yXHdm_i1o7wA)3xGGHr_p}OIthCJERJyPWq zc)@&deK+@vY>HqIf5otY%Zt_7Vm=q~HddQtg>~@AqEYZgZ83`9 z@6dx_apUpCf)YC>d7sp_llbUa$+)-S$`uyOGqz98@Pg`MMm z`?PQCwT&iz%O=O8x%Eq1&@OE$3bS|7r7A3+;;LIW<^}uM*wA{~Z_qC1AB?Yl{d1`~ zrRJVbNmfAhkP2SRg_hemP^_Me!NlwB5ZaT@2+GH)e#-t)^iyN=E=j-X!_C5`WA%nu zlQfQrg1m&%(CBI{Hgv|UxmQZ)sj;(>PzV!O|w-GD41Q8H=qjEdF>wcE| z`l6wCrSrq0S0WXyCc-?7Ox;2B^K{Y+pKJCD!w||PaMs6P0=pB%{Ml@+88FHTtSHT6 zJTTB1zP#BAkonLpkq4%wG%OYQas{2QjN6@PFp(fnrUCc|q7HB;azW`hy{Kn`?T{z0 zpg(ei9k2`N!5%Y5xX&5E*s))DpfF#!J{u+kKFv@=?~UMV%B5={l0teAM!JlJ$vTt*`0ajnPmxe8R<)SXNQvlOC=R1nLG;ys_wmuF2USA3Y9Hc^jCipJC-Q@Y;A zjl(uj~L&}0>K)Ui9=U~>pKj@4$v^*?3Dp*dEAIdtK z2?ZAL*`yfhM4A&eHTWDO1EE!)nM1LGS7$3$VXjM>z|j+t0T`Hy@*{K)w6Xp+(YrnZ zZ;u_tEkXMT=>Gbd0q3>L;OKrfra^8!6ipX^)NSETu(T?YF`s%e?R2T`3d@EjNkHp= z2^T7pf2;b@S zHGj|R8AgcX>kh3hfU7^BOvU2k)Ys!Y~ z@#fx0mEm`dS=MK^9lUKb@rDQDUGpWXc5j;t{?hr*FT)=G>ww87EfGSyHS`=`l-h_h z8^|g)&)|x6`BQcB^&&)>wXHhuD81I}!2s^4oIN_%lJ5HX)$o-O|(_fcAPJ*pas@0xQjc<_BNT5Z56vxEkA zqm*SB2lOT80$e)WTl>e#1msh&Ti%~raT7-Jt*|lmB}#il_EyM=~3?bG-=`?YspU!)jp9I%md%x&SnLstDg(-Z9~!d z887}yXC)=Y+DM-wNql-)7M}X>{uO!=bj{@J+db}``jJoJ`uh5P(8OI!{rOEfR^QXHx}u}h5nmNjRj#`7CXJnbk=BG zXQ6X+->3q{jgo8UjI_mu0a!#du;`KOK+=AX9ikh0#tYQRQty{lRK^yGS)Y^cC@q?Q z;)kpHRm3QdvJFdE82>uI_|>&d{c2=kM2N7H>36T6H4!yiLn~0S2nAXw)Upmx@jrNa z&2lNXs^?{@_BMB;cIV!-I&~rKk#7|Dg1yl!7LI1NEd`1pT^%Q)B;#&=Nawt$$kKvH z9R1T~=lr3KyN%b8%}D(?>W&DsWrBHt>Nb5?D4|~-v(ihF)#UNz`w_@8$i3gGtR+7a zRGOKoXW}^>j?Qi`yZ@??C3`$8XhTXAhY< z<5Y)s{iAIaZzTkDLJojBG`(y-P%Hl4`jSVD!?)5ygM65hE@%7AhaPGI$dljS{T7)$0+xfV!7(b6)4n~Fq z^o956eBC}w>6RuyBGM;F8PERo*vlqoVyG>G``G32%A*@D5*kr+RxEk1YNS2580I~cZ2RY@&rD%j_e!<^sPw%F#3sqJ|BPD!qGMG zFWq-HBF31)Mlw}}OjwMLj@`|77|qL@Sgv>ixxRG$QJkM}r{&ONuPuOB?5ML zpxbI#`DYX+uNqxTntOT{ zors3s5gKvo>n*nk{IMGA$3920c#c_g47XMGbYvm(-I8KrQ8K&}|9e!hL^Hss;)cJC zD8X>+(goGBxe5=5EzRB>pjYNbERvrV9!&ebFdJxJ6#z#s0K&E3Ol~71`f6fznK)Kv zAK9=sM`0#jXRaf?Ak~GUBmf1_z?^!F!lpba(ITdKge{&21Z$DSI_Tr#LEB^AH$lq7 z@c>7@e-x}6HH>ezx*F&Gd(16#lHVdZGj=t>Vrr2~rE;O9Rb!>}DBElcMmb-fzFf|( z-)v}T-=_m3A0?;lMgOG>1B?r8fTqD8{>B^jQH=_%p0>9bTU*aF2n4^LV%;rz1D#5! zXMxoftpc>$Ig@QyHa`1q=F|I5PG?`4|H=@EKE+12M3;Z6Ui_PXln1~t;$eH9sE3L$ENH0uYcd?!d8G9*a;riY3MbiKfh zN=3f;IX#A@1<@p^xO8a=iV!4t$J8k4&?ufk$n!F8+0vwi`43Qd^L%=*y2+thC!RUp z_W8Ll_S5ahVtkJ`&tfTfjKp}>^N6lP^Ggfg7V`)%vYRLj+5_YOtst|ydb=(UWP?=c zADE|K+-#1(nn3(tx}ZT&=og+Hg>2Du$D?;xaI^=Qya4`$&rZnoHD4-~%CQgdxRrWy zkgW$uC^BX1ADUw0VCxRj1A<4$#b021{NG_X{!IXfZG|ns>zshcJUDO}vUOWGeR1tRnu^Fq z)6QUX%8J!U*BX@7FjD30s=@#ii-Tqd zA(l+_V4JiVogNmYP8VIK<&_RF`74*|ZL^Qw0XTUYzg&5$O2CRHTVm9^=b@+D_@InO z_tTCHOd@D~(4W0%lH-Ka>NRr}H(o5!VwV2g(kn$&Ykg#xl%t<%rO~KmV8A|vqt&0! z+3>kJbN*YzW*~Wcz!i)B<=OqPp(ua4nb=UYEa%G-F6LEQiSe z>)q^TZ+jZ<+Pnw)l60g9`j{hkVo!A8d}|mh%rqtbRj94;=txn% zrFjbEv=QQ*Z;@xTE>5GTE{;^VM3-fM6JLD~ zLN7>f$+N?<>}**A@MFNI>fDVeL8sOC=gVFxZYc(xRJ-`Bh(UE%wsw-FlC}c<@O_30 zbk@R>Y*#=`mJVeURp)%j1Sxd&bKGpNJ%&2>^k%5AY0S#+lC<^&xw^;KUZ${`7%MSV z?x{|R6cfvEpEEUT3jAUCh&k!~di;yRB@y37IZjrMn$71SzM$;Ui(EWTd9m7sjasY= zI?73kr=7VU8`tlbj6xs}hDfM20#U+@vPa_4CT@hdkfZPI_x|o?)4LePA?T)YpA{F^UY^WA(c%SyR~DHr{>_FzCU!=&F_dq>ARt%BwOsw9 zGM~kR?6qWdO#f!az8-OM=4A#EJ##%7^K{L8{rbG?)rl&7jVBrzCs3_*;){1FZnIrM z)`kPhrb6$m>nyh&0%FqKJ&(|FnrEc1)DEpi<$buNunN0R8%7f!X$5gK`Ht?radj<9 z?NjcM?)c@v7-iGC&vn^mT|lT9bbk8^bT55SMe3fkT!s~=Oos4`Xsgk8se!7rXlWWO z%mCN=eB}wEx72%J0Fk7Ee0Y>mihYgXk5s1wez$Zq(a;Ol#}03}fc50(>wjB~-c>ll za_i}Q_|i$sL)|7=cxvhBkHIq3i7qd~+<=KL4WxEe;JNT-m#n#U+gbUJ7WjCUtHd^> zvHIw^`o!_0iJ_rg&ekpMoS|JrwK;JhJ0>7*iM$rLP)541(N8@+!AdNZLqD&nGLOFh zr1sd$!Ov3j%%V0A!mBFJY6=OGi(HAWVQza)3H^d@D*j7O`5N0SX@^b6^Q4VrY*%`@ zf4ZzlX}Js(1#%ytX8u5c7C7VfvJW_G_KiDIm8MkA1!j3NE0kf)oR zAbB}g4Am5fwUlbQIma@Qzj9DkAD*M_?o)QN z@l;Y6K7+BVBH@L+=ISte=FS-qr}G#mZ1TxlUfxVF8tNyh(Jo1CgJ_Zss%yz*Inu-H6O*v6xmSOD=2CiCd>Q?Z_<@1mD)`nTPW`5N$wgJac_n${^H!}%u zM;re+VqyV)-4BEt6LM>c{MP)df)q>hjB<>{C7&cko1)pq8mh^6pPIE)d|W>oDoWOi zy8dIfgu8uMY>zcYWKvg z<7ee!MV6n9{+xBi@J5HwXlXsCAL|oRJr?u?aS|IJ8cY+2ks0d^3frH-szGfbBRRSh zxf6=@r5`5!f{$f#cKZl@3RyfmcC_YB7_N10lgfSz!=u z)EC%U0g)Q3G!XFQa8-h;5JxQ}VRia**LO<~>&jWk^E4FI2PQVpVx5ep`keImnX~pBChdw;XUKbUXmr0E`#6T5@vVON_oE6`KGc4+HXcG+{1?G#P-PdJuxT_QeQJHu|IVv( zWlPcab47q*vExr^WI#zW({q!5bBaW9SRZO^AQupE$R<~~5_Fq8Er+@fX3*T9vtB{m zxQ8Vvq%A$wY zG4Gb}{jYuA{rjsyH085aTlS~1e}q^O#3+(^wn8)QX`(g!HKOg`t-{in^SiH(*JR`e zd@B*~v%)PvS9zd?AZ`f_vIPTPBl#$pKRm)waeY#Uo>Ya#jo~>S>~ilvd%vKK!_Lk1 zj(fO*C4#z%rKD1O(=0#Ao$L74kk`%Qx{zlf5?cQ6{!9-3plF+565U6Nk>m-A&su|b zuK57_f3_VS!mgW7g}WrF4Z)nw29q72V4#|k;p>_v3q1ko*YmX`vFO6uYd@>bkAHYs zwfd@;TbPOiqdMqD7WW1IkL@YCtp~nQUQ9t+x+&jEt4_4eGcKMrB>JzMbGWwS>Rz+W z2IBCN#||z;Ppt}+55Xr%3JtrB0(~pUkw-tgHs6hUm8WVX=B{dg9Gu&~CC3|&O5<8O z4;mPEBJFy=T{XP%Z5KJ9x@#xBG?fw2+#!;6WNt1Pbn+S_6Xa{Bn%dk4DV z8{A~2_wy;@<*$D`tH*}2A)ejaS&ukCX%9{fInP#BBq>aPJf)#NR-ke>JF07CTByTd z(_BjQy!-uIVWrtQS}OQm&v42#kx7Gs&)ApCpR;OY{HIdM$Sou8N&I^GT?m$BVxL$f1oOARX=Fk~07#N_U1mvejpXLSzm>HJr_-Z@R>=sdL3{^;H zW+oA@gN}AJ21L5n_Fb=zJMESzTVxY5J31@m&}E&@?B-U| z-dDrigm(BN=N2aF)ipN0*%1K;UV>L7A7`obE5u1xF-ws+4;K^?-Ojm1iM!W@`?0 zC;uYq=q$}>0ZDxPmbtYniO=L=l>#+?=WLz1pzpdw4?1}>_zjPi| zkmxuz%DLH#ihy0*fojJ$J@?LKHrmhJ^gMTK7uh7yfljT!`&YT8?S3uU*l>SEsI$k6 zu(wSs=gc_r2S!xbBh21PB$Ujg?{!npu|Q+TY6|$kF}|^ZC(0+PFq#4;+OHS&)jEp zhDxY7<+D&tL2=Upsxk7(bimm?HrG>=>qe}?C(X*_Wl|&+QB05euV@d|ed!`wzGS!F ziZ4An=b?BF_s2EFtDl-CxI8KIhwr&{%-22C5SDV~REV{A0cBAyPJWcuJKE3r6qTZ{ z{;^&)n;rXT`Y@5=34n-=Bg{9Tgd#NRq|KYGD4W6Yr%c4=8TZrPSHEUAMV_H7SSGO6 z_3Vf~1QVrcdTCbz)VXQbS9o{u+s8a0+c-<6D@9PTk*{Qu#PB8Vac1QH;UitoD=q!e z64pWv*J*a{@+U<|ljJYNI#igd1oeLLz!0L%CGe^`#}^(P{W6HbL8%TiA-@qx58BG} zrDxma`^Cn))O}*E(~D7c;JQmk=Na75Dzde4*lggJ3cX;}y)KRCv56(*OMw7Vac!EH z&(YQBTS0mxu6xTblTAJU-OZZP-3o2vurus2zc!6#BbKGLt_GtY#Wcv>#}f;k1dVJl z75dKmDJ5DO??v->i}HE~HDV|QD*V4|-xP1P8B6R+l&IBgY%J@EnRbckKBc5eLto3q z0(EI6KDXxE_s`-FLbf0FsrO%P7l^oaG;7;B&_I(oGxmqD91s@j z;wrwAT+&JC%&WI4ei$Zy?a7B7h08W~tgo zw{k_D3*ua!T$1Y?;f*&#T%Zs#C*iMQ(O&_m<*~d1nuHS1;^3Vd&bKI7b@-x)Lv){`w|j@AX=b@MB0@l z;C*AnNwZz#D8J=o38WE0C=}OS<@3XYVPtim&KK7)&~74^ALC?bl7H#WLU-P$XMedf z`jJ4v4?<2LAWz|<#2X~pLjKj1OUf*<-OuLEB1`}D1~TqrrcXHJt{T6ppq8gxK;^dW zVhUA7YXh*+(tJ!Cgd}5czVi?1cOZp+e_AvZG|qpHuSx#8ysadu=>AUFI#vIZg7pdV zV*F1e8DLyQtx@&xLby%^M{43+wQJh#akea8DNL>_HXX@0;TC2*jNq&s5Zw?jWSUt%ts z75{)IFP~)#ouiEZj_9j4lml?Q_n9oc1=F?E>$K&GFSKW=Ta%;o%@_S}WXa$sl`aGR zv1gd~BHFES%c`0?)ou@7KJ|n3s7ie2Ff{Fa5EjXwPr%16|sgs%a$%D;#FN z`Z`WE(SGkjzOUz&9r3Jo5Lt?CH{g6ZS)=J0aSLO7$vQK>tQ&n2*&teLJ>$Y_vBK(5 zEz(|-#1qccj>wQ?m@8*1#Lcm&-$ECh|y8N zm`A<%;QqvFQZ0v|Dcvuq_aOW8e;ou?Ehm#1arFbbFr)KUbsm^K6g=V5ZLG<5U$9gR~ozftkDBLH>fWKZ@DQeb(oj z9CLWjdg#)}$5ZpgAv})8<=`yKwghK|wprD_`%e>(D0snmy|2mP+pHh?I;K!n8_d?c z&mqnX_|0#9;A%emUNulEGvI|p=NY_BC?_NC+0REpz7&K=03VJ6W zb9gY6GX|47@tlqqG-qe((MZ{4m93aJ%gMA>5dO7hR6mb+LdE} z=`PnuP|yDxKLa_H4!O{J%`+4C}E}uVVcFpmVNvHhV^fV6yy{ddf`3cDETFH9TXo6*BVkL z^>G}&(7oO7{HjBjX4g$%FqwRXX;L8^_#3}qKpMeNcp4h_A7NsS`4uR>LcKpGTa;qg zhAanfM~fkt>j^65buma;O5&iqhhP$HRy=?|z@Y!Mm|RmhxjXb7HFN$O=gW;%8VyY< zPzjaV2O-C6EbZYE`J?V!GVKI*pPqo7o-*_}3f-k_-bkK$ge-uWc{?|8Yklv@^@3Glb8wIKD8# zzr~T~1cXS0_L@aL^G}@YU)yV5>!E$-fCCDg6*t^J7wpUbW7X{Megu8kIny82)nnjg z-Wohe&DP+dlK$5$cETUEFdqMF7hN}skVf-kYPBVr#_*q60E2?4gL@xazwobB9#Qq5 zv7hTD8N7L_0^5J&4jvQ@yUzm7@J$f_iU5HD0o_UGyk9&PKVwa^CO z6#iUfvHV-~f`v|O&fNv>krGOdP^dv~b#;pMlKOTMnQd`KAS$&2IE?>2W{0qrX9{&I z9^hj#2wejfn^jm_&`hcvJq}Vb-;!)31nzY9T#?_`I)7)Dpddrqiz+jZwl;}#2%YGx z`w+l*0G)PQmkG>vj5l|D0*a~q5EPfx&U-v`F<)ZwgI>_W=ZHRNiA-t0eZP{1Eu=lg z)w%RNc2)HJou=cyET6WcVrXRwK^kGXYpYqG%AH;wLZP?}d`vd)V>V|g7d6wCn#!Wp z+93ANf$3tz$QC_{(u{h15Ll%A#bYNxn-8H*C{3}o&T|U3u2KM}C#keXem_;+UszOyA9T?0P4yE#+Ejs>&kkq?*_AiYakJHXe03ku2J1k1p); zWsDt5ShnSsk%_+XexXr4+22cKD61};eeml>;h&|=`L8gko%~<*D*d#pem>_6G^@?? zmELUq;1t$4al!vY;P5D~48jh6?&xb7D%fmm++n~qnpi@>9#r9fqyCjT901lulLiGh zUAgJCuUr%I#I6jv`++rfNm70V`iSzFAej3OP8#Mr1UN#+Co_V=! zeuDtRK|@bIi!6SF#V?ti$h!u88n@Q&&&&Mx6TR-1&O0xjYt75$tQzQP+}eMroU?N& zN;ciGMWAT6g|~73^4Hg%7GZ6uNHX-e>Ln-s8-uF$UL&5occyS67m7jkqW^pTCZRGX zoliN}PK#80mCV(bo?4W%Nu2x&RYFeXp)cWLkd8M?pTdGLA?wy97GB$Y4}K!lUW27R zjHj{+_kE$%!JA)I%d|oFdfXu;a%*@D0*}1t&D7Nu8g27&d?nyr1fNscKtuK5Dp zGR0&G(%|-osS$bt8k9vC*Zi*OI@~|5t;Fu_R=2fikNbhacHjO8=RfyM!rz0S+jFpi zFbQd#@jPqY+G3`Ruc0P?8%K4anJMD4ZP<%D(foogqlt5`c+W>Xb%nm2qp=;}r|Njt z>bXjtLJ#F*(SRTXDhn+%mBbzp($cP(#yJu_$T;kLYMY~e2*ug|U?9aJ4 zC`JXx)M@-Si%7a453m#KUpptfF%Z@6<(W@x9A9DKJG@d!Lye8D)um|_9o`a7x5dWN zZCs03)Tb2RtXjbib*TEp%_hh@yidA7b#(|_^HNfIA3>wu;g#wOsjVni-eSyyJ`eE< zB;(ts2WPn{lQhPn>ZII!iq*sCzWvTFb5WgP9&JjOL<^4wO0RIOFtaVpQS66X8WYmf zjz%%fJC(tgmZlsHV>WfM8WfAICHPGu#!|Nw!sRro>3XiN6-5q%1uacoKqP>dyxMzk zI3w};2fMsnX_ICC)*xXh6>Jl+(5vJRu;<9R$pysiUpnV3-jNKaq0lblLc%Ab2S4*e`npK$=|C z(mS<~GZoIL3>+xxtYf%CVjGG)8KVv}+uA(eI?R6+i%U{)07g1HzaOXrPQgc78BJzR{t)0H7Vr}b|fjQ!0CPEAuhKfr{BtK0%rCBCBeNT z;5{xvm@5h3Fj+3k`$_A{%AD**>n76cTytn1Kis^T6<2NO!MPmAhhx^m75K+nXcZB; z>rvOP7Wj18+7x3ZTD3h?B?jNQ{E*Wb8g_ctz~rJlQ`^+S5vnv%J7f?&-to@0J-ezI zy_h;ql<9D}8zd=`P=UrJr0$~LKu;Gb+t~#bSi;Pf>LLAH?0@O>t4_wT!{4c?b+xa9 z`U>~KDNlpxs;w zn%o#DCK{yMrGv`1=?M=Gq9Yql9{#wa`pUfP5Z%(I9BXxQM&%SZQR=T$4|r?&i|#UU zo%Os&8RrQIfP9}?s8uc;P0JDEn_JuI>!_h!Tez*CkK;4?T2%8r`+&cP7~Ddyix+c+ zhH|m%1jQh;gMtq4TB?5Xa$|j3k#aHQXlhB}Y#6BngPT0%_wLWb9N$&gGei%XUmD3l zxmF9A35#|St%WuCTj^$bgJ)L=d7%`@(+i>w^D`5CBiyvYT6S)H@u z5qiER>p?|9JX0915z6YFP+IF9QoE`x?FOMb75@^Gvb*^fAy3gRs9Owiy^bw=-t?>U z=dq=};wJBPbmR9N6z!H@j(39b!Pnybr;!hV^VilHh49|`*)grR{X3r@Cik*Vw>rBe zaj8YGb$W4KcF$;FTjvN~p~F61vKyOh1gloqPXTwd<6RAK&<({n0^;bj?2U^fk<9m#i@YoCg&m};8@?FLRfqn#N3ag?vhf7`;Z=Kg-D#^x%Cw%W{Uo;%X>+L3-H z|83ZUTW|df3!%F;xzJw+-`$OG3x0Y*`%AYCeXg-?NnC#meA4G%;cfJLf9Z}Ky`W{# zro$B3wwZOd5#DFo@vxYj785~h-&r%O6C||;5)gBSdWTb^uQf^|Khuthi?rUT=z_FS zaYHyR#2D-xoX6Qr_u}0kA^U<%hY{Lk7f3i83A^rg7_KJw4+-HynGsr7jy=V~WA7Y$}0k?H4- zB6du7AjkaquaZh5p4a2&b;k*^p5@XC1`Ps??rqml^ouEOpkG`hO?+F>X&m-+=-OVK z1K8*euyi6$Q+8{cGrFh=fy3*u&X!k&UBzvbo|hSnqo!UlT(2WMrQ}Rajtpp|sSzQ6 zsP|_TE;I#U9#zHsDcQ3&NL0RfD~H#^{L8{ZD8EHQ-2ujz=Js{1e$IX{Un4!IO525| z=^aGaFA>r@3RhMlZfpFApAm{Kq{tWxqvl&GnsZ_*ftUS+YP(fg$yzIQ9x7d zfnMW*7o{o8zt8Nk*Einw!1ne?{2~VvS*JE(6tid$rKAXxBZ(5ze06{95kjTWKjx7? zZFo&^t5ZGJK9j{TYg(lo#keA*_Da55uG|6N!sN}WEwi#veqWk0b_+&(&{}>SEkU&Y zOBWB~3=K@hFWuk`5R@`$Vu=P~O0-MRhTUb7W-@JB(j-D{`rNY|s=pO-5`-9xFv`8M zk04_+0e=0lIaS0q1Wo-*mrTF`M>KUGMbiagA^#xa1QjAcdlZkH`ex=vy@3o~ z1ev#xZ%CrSHNQ%tYB8F!T??pcVzf)BsXA*2X&z815$4nzejtT}+egk}sqcq{|NnUX zs`POFUgWf+9F5U7lXgk2VQO;Ah#6@A#??Od6ETDBdjNLwzu}su>Kw51oqMZuaugHg zA0+_b{!14JZdB;8yWwBD#ct#llJ;vgD_7HPDm zZsa@h-2XN*@vsdg-#7yM(k2u3BUcYF3BjFU=U~IjyG?CCfC79%y&R(Q5KA6>6vH*E zMH4>c=zfUbH<8GNi&Km+lm7iwqn9Fk7aa7TGnB#ipdsE}f2Gvrc?ELn>8);W9(aJszE&#OnVt237dd(2IQ^P~G95ZaB$Ff2$ z%}&QcZTK@ZI}WUuQ|GCyB+sW5jeMTfQ`=YCIeg-f`PFwv4p`Dp&jEKMmU42|C2(3d zynk!FNc0=w?a%A%Mmx{^uGVcgr=RUZIuxE-G$xK}Nt-*@$Fowt7Tn>7}% zJhkN~Vio_Y`EYR3WMFtQWm265bJ#6ZWel~I!+dfpJZ#w+%r>k{GF%h=&5m3MMZXgRd zSDefnt%OMo4QPI*LRHfOZzhx5)rz}oMuS9+;rhr@B76LyMi9DXf(^H1V|9^&&WB5(H3my-a$Up=_dcvr-z&4MIW6JX5UneFKP^p1WeUsMdOxsM z63{a!g*DIM<%lhG$2)t^VH zP^TcF*_WwF6}qR;MPHf-9Q$^ViKy81_7#=Ykq}(MI3jEqdqrG)Ls{unXLe%39Pdmu zV206t<0q|YZNp{SYSQ~@x5nE+KZ!l4kJRGwbb_^XWW9HaA0{9MaHeRhBR_;?c^4X;0Hxwm5b^y}_+4M4h@Cyw@(? zs9_X#iN6P-TTK2VaY4T==Tw!W*v#Zi4K2)6&7>n!Xt*}rU}8a3&u9-~COJ8gnV=AP z$q0_#gt%z3C(YD@?WF1YHD1J=yQeoW1cMViAJ7q-spUv zDcU@BY!&tqMtrhKxCkAE%v`Gv{xar9Ob(kJdYjhn&_?{)M`Y z$cnV>t>x8+ z9G-8wB3m^-gSfjR@cn?risQnweEk-kg82FPYGlUJt6s$@BB|+HLQ>L^PJGAl@si&$ zPAL`jfrhp`raXB++GX+!R*T=8-7xo*I~nHK$Xn50%k40_c2G6Ctda3z+l0lmyE+gzET{i5U+-o50elS_cE=}Wcb382K?3!7ARHue;VLKE9 z&|W)*U%XAun9~m$X0k%2LZ!yz$*Yvei^8L;UDk|Irwc_3r-5*l5nT`4OmVCAV|Pj) zOmkNhN@FH>-1kbIP-9cwNe;cpoa5A6Mho|iTJN0?=O zb=kbZfJ*BE916Cq6a6!>&z$lTXiVV9dKpYMjOqN`xp#ki8naO=80v2PWE$>2k?gQ( zTxjbQ7!n)gpC@@ryFhq6ie|rGJ*44rtqkCdIzwh#Jv{Ovy+I-)%Bqnwg{LN#P53?R zmVQm4y17ZZ4At5!DCi?H^Xr3%c6_QulrQt-ull-ANC67>O0MsD8$U{jOEow7LYk%_ zTLVMt4w~ULjc2Ij2>4|wMIL)3^X2EohvvGJ;WjTkG1pS~!He3kmMykQ@126B_B{8&o}ZszBx3+cv~G3^|9%I_1?R^SU9)rBGA5XI zhorlz5~E9TCDu*1pFEnQGa}wmU;rXQ0RwC~^+vpNyO`gTBRL@blSMh4jsZI(o0XMl zz)vnQ=fd|AUNelF`LjBPYcJK}TKmhx*54B<=IW3Hu6 z-xo+6@0I1gE}!+-bI83PFpnIGV7Id#h+_5-PHw|R8DrTHHypXk5-ytmX)iV>6y$h? zTn)c!Y<)DtDzs{qduWAdG(n&8=21d3%h1ZQR!+Xn`(@^2YymH?u?N>E}~kA2P@Rc*Vj+pUuS zQ|4wxwerfKYxxRRYJkRr7^{~co_y!yW7Zt)z`6e-T_(k3x$+|PxXAZG=v20qY}_fs z+JR}opt%x#jm21)iU!fMnbe3S2@L!C{-wJYPrYeJQJAsjhyK__|2O-HZw&Mbo{w&0 z+t+d;Tkk1<$Q7))-WxU(w$54v*BRtqeL7g=wy>1l%ck-3H68V&|M*0?>sHTRzCVqT zl5~gTkohTy`W2v!D2l$SAaHCii-9k6S-@9YiTXZ(66MzFY*qf5@G0Bpuq0$~o^#yD ztEMMTvIIU-G^o^L#<{nai#x2^ zUr-$r3i=@WPW>3#alhzZJ8Zjc-jr!I`ZZU| z!t&nlrsLZkVo^t@G`}Z_CvYfd6};6;z>BiFq-#!19-H*TJgq1xDNEhhT5fi~f05mv zlYG3sjEMS$VxYBI@dY=-SkEeABLsEjbctiSmFo9{mMuMUzAIBRA(;dM<+_?Oa~=ae4{@JF^_qw6J(a;Z*kml~Zy zBstfl35G{wTy33sr!=Q*(ha#QX zdkrCjz~7qm^P)&iucN2}2L+e?k#9Ex>O?^YL8)UlLZ9!r<_Mgoe&U&%TJwOjLAXIoA&8A{h5|V znQlyG?;+fD@WK_dIl`W_!i!{5Oxvq0=Xd!!#&P)-KbN%*%&KSBVAv z<2Fa+iSr6L5C1tbZw+uK9;gbegXCWwhDLWEaQTdpZ?M)-Ug|?)sbUg33su}L#fp3N zVL$lWofqd-NG6~LVjRt~-r3gwuoF3suuNyR!I46PgY$ zfE63mX@XbU$SoM48&m?2s2SnCFyI1bKv~L^e#SWtx4_Gv)83p0u<5Zp5W}9Bp+vRO z?)t!B6)gZlF#^>#py)>R$}&D$FxB#-0heCn5(>IEVJTgav+TQ zuR!g6ZZhr6G>IiXS{&fF^#A4e$RPAPF-|Itq{W{5Byu!Vr4Bt{yO^YtJVHImxo}7W z$k2639B36Wb4%XR3je=jgDQ2x-i%MC=Nw_>NzWA;+W_zYW}N=%*iC&77<%8e{9{Zm zf8smjgG`;v;U!95D+^zJn(al@wE4%j-6F-rpO~K+6rS&k?0q1r?TA6%Jt{y5Ju=$d zB|J^0`Cof?63bd%4FWBvO)g;+Zg?K8R1S2h4unma$a)kO>QX=E1Ocb*6y=Td`us{#v4kzV9xvjWlj=5&k&DC* zp2ig?xBnhNcz!VL%qHoKE;U#bWI7c=rZW$`i4DrCSKALmQ(hw1Y2aHGD6+{O^!WTy z!QQ`BqlTRNI(d;BtQXcuJ@mn=;J(FvBB=I*D@XqPziHJ{<@Ow^Qd3@C2E=GsKba?kZM;JqBtVbAK6Jbf&HyQ#hu4OaS8c#|<#n8F03Rbj6X5F|W9h4?JwDK*}S9|yp%B>(rx$oR3 zL=|b_b$I5O}i;p{KEFP7N`+Gu`(-*1)yoj}atIHZ0ekB9AV_ zdLCtGJZv;~YDe8%8(H$4+~*gWtiJ$P*X6Q*RX7-dcP~=LZGtXu-Pf*Z?1>ZC30(tS z8M`UhZn zqt7cbYsev$Tr}4VXi_rs$%xEl-+8yhYqAJgjP! zdW*ibTIN&+B|a%MfNqIWz?OQ9nKIBuy(DCKn-%mU!G-uD@n9KoizpioSOJBv1#PI2 z8|7-Ieuyl(JivL-%&8BEF~)9S0qivOWdcGn|4V1**Ep=pu&Ni!BRV}gp$@9xTn(0{ zyjPqi*JOBtjC;hz>_TVGoHBm+N%99-AcAsnlg4O(v4Ttj&G0>*Qw%B2J#W_I&G~r% zl9)ASPxSZj)6k0Aa}o)51N8EQ=djz6)1zDP!JAwAp4aP5N~pN9E=qL*$Mx&*F06>| zqEik9;*+q1rsa(GEuwjWxw|yQXLTcRzyJY7{|seIfmj z@Ktf~u7HlC$+@76O8vzMibOM#Xac?HKe?m|>2tAO6ZF64h7*Q9Y5}m|+Y(Ck47+J5 zin&_O=;n21nu=Ll2x-%+ep~UAZ89b}g^I`O#7S(8g>m{y? zhUT6Xn}#ub|1f*CdogD?e;nDMEn_b}cXt|gYTBYmJ7xC(k4>7}ZY(nx+19Fw8|X9F zZ9$8qx}P9L50GnrtbN_x^{t_D#BR-{v!>3@?<`*GfZx8o@3S*gpXElm+4}>%eUqYu zKJbLjn!}i(Zct9R0m)ENHGB%mFags!!zd=3cY{l`+nkYZ1Myi$WHd>NgRMtcQ-UP1 zr7Yj~f2exzsHV1Pdl)MU0xBX>qtX-vlp>v63rz&1h8`6K0qHHYL`3Nj0Rg2&q!S<_ zCDeqD^iJqidP^uFkaB#^Q;9oU=qL$uWtyVn}G z<*(+^$bY9ataZkM z%q(t0`dbk`-|0A-!Sae~U`gRzXzK{ANGq9~t@vQ`ZEB?gJO2f?d2@-UPj*A%Pt(H2 zq6bTiGJ~~ddx>P?{tXh5Hsz);h_KCX16OryGtE_Sx7T$~S>z->9_koBsChI+92r+wQePwqt4@=zcmY#vSee*CD4foF9!O#yRz-Uw51z_REg@Q{Z z`sc-)d3{Ply)AHnvx56<72QI3N*@JYq79117?7hIT{(dDRq*GnsLLItp z;*IubQlF=_mys3BY~TH~{D1%FJ=Q$tBRpceo7GdKIrZg{=wNKavHUB7_yzRE1->m3 z?<$>S=AtSQq(2tx#h?_%U9IZl*b$n1Qgg02^ZgCGf0@S64=g^rOymRld_P=;pwu3DDqIJgZjEi(XvhvTpbBu&F^4F%O!4KP<2BM3N4e zIG$_TG2lq;KP3jNNl^9;l=gqw0jv4aqyi``xS}Q-8H~KbAij-{RHU&Z9@yZL7FcH# zbVpvjBLw&LORw`t>kR4$FpLZd zA5tmgK6ML;p&fAbYneIf=SbJIo7>Q%j;&_#FYvDbmlO1H8-8J3P>`gVBWI)gG<>U5 zI9{dA=Z2W$Ig{;M?ibWNGHGyoE#kjSrpXJCE+m7&LKS0NT%w+7A!Uy3T9Q^!cqU&Omv@TGPJqAb?TQDi8_Avl7Ta#JBVcDJ z^c==g_l^+;#W`aCx)b-um_of=kpQQkN_faQN~q_5i*9S zx#B+10q=A^sn!*p+u<{RH*;)5=DM!LM7P$>r40N3Gip;Yk_DYcI+>h z_?#mm@-!ytzbpRV0TQMlxH%go&RCs}T<$^OkNz|PHx#(-Q3p*pqJz;i z28@`1m`Ym&x30};j|4ptPFB!}Ok?KZT>(hRi5D(2+B(bsXj zz;ack)diili(&g_!*VvK+Z3J?`&V@y!X~TN4EXngPi2{PEsp%mMhK_j6P}Lbe|yF* zo!RT-BAw=p z5kyQzXZD?T+y0BY2F0~fWL!73f7vb)=;@r_j;MqpcX&@d%<__rl&)k=p-(db5k=X_ z%TxXQEQgpYK~_YEExYXApD>Os#!XUj1b|}yecs{Z_5a0~dnl_^jTvhgFz>nW+5n1M z^Zhe?7p8-Oizh75*Rk?KAJ!?Rn%UBWyA1CU6sHU>UUAH~ER5Bbovu5@Rhzkm_`;uB zW9%c;A9du20YdLiMDlD-bH&~6i3OCr7LeiKI%x9J8E!(7>s&FXz(uET-=wee=opU(!UV8_2~M*Qi2YkG zS%63>3tupz-S}425%e2})cER7dpM9IatAQ^S`MZ$F+#l!!mDt@xYOSs*0!8#@kAEo zW!eq7TEf?inqFq;lHi)2Xf3unqrxK~B}ZPRNXr&ccB#g&@I`Ed`k=oz(dw~wRpp1R zs0n?=8yhhG^wj+cb)gNV&Uyej!k4_jhaBpet-im1oS>j##x)AFBEK6wbT5H*yHwNL zZjCdlOVG5k1#gcq{^d|<@@Y= zNzf5Op(E(Gebxe1q!#(8?j`fdx}7~BddtyhlAOs^JuK?>;2|wH;HY>hB46^B9lwUw zjfp(W^g@LJyA#V3TPLjEM*N>f_#2?=dPA-ozlES2IRa0zf37|FySxm{bM102_hz*z zn;Cgd+kRgpHXXqt(4J6Vp>=NqS_qh{i!PIZjU1UfA_5_QGt@tZo`;}PoIi}JI>67c zTAd?1iZCC5maG}MUW<}1xRQel=34l~IfiQOLS39!QY0ZYUi4iP-jykQ#sB1GAdF54`{xkWva)Z}W z6}GrsdP?*o$Bx!55XQ0{8i_4SWPJBVY!?<=s6HrIRksAR=w4?FvW+nR@5_ofL5VDU z1=0)XAyXR-NMHLP9rYZiDP+30fEsSXCs{gi1&bN0c|&}=modeiIo0-lhT^+pbG`2} z8Ye()Uzi>Zyixk;S&nNZqu9zVf;V{-AQRMd(0$~!Oeo>-%N$iUz`>zs`I(q;Q0DRg zGrw4{q0WhOm|D*2r@qdUOCn25YE?IpKrdL^mI-u*Q!*%0`GW`JyAPl#toH_W9x6N) zQ~@|mZFSu&a8?MKle4Ym5fyrPlq*!20xyYb&bH zu!FBm(X=Q$4i34P=z31~Nz5mV%+T%C-r=}^TF$FP%w&4R&yC@nhiPiTT)!8A=L^>s z;MNF^W(ZRh7UgTo-~FvXvHHB*QLRhjng0)_UL`Kp$C#b>NGu7TD_WP{3r5ZQzUVOe z8XPAws|GSZ@v|Y!*aw6+al~O!Y=D&81{k|W(Bi)CY3KaL$2v5$FPJSLn4AXsTro${ zsRyYz2@1Y`{;M>oTd?&q{IzW61W4aGi3Dj@6I(nAw`!d|XUJc02I{DEygfDQPZm29 zIyF=cJx|$eg`0$RQ3J?wNzN= z!Zk;NUl=K2Y}UDU7u1P*3{xQ&3}FlSY>3tXH@K`l zx0nKiXJ_XFMp z<&>09^A{!p{Qq`OtDfjM4yw<&f0=-Rm8~MHC|WOG_G#Z*JOo%q4SWlrPk=IGghCaT zwGj4kST7#uoHp}MYnuPxyDC$R(|Ncw3YZFZ&b*jWO4C?!y9`U%_x-C?lOXY~mMC<| z&v!YJKX}mAOjZ#cZuWJ4?oApZ6D2#|_;=1SW8q@Kk&DQ&^B$1&1MJb+9!l(zjju|u z?z6NtwSpvg)U6la=^m?DBEk=qMsCxj!GR2f6Kswbg) zt}Qj}!QK9yu1i;$?FfXi`XllYJzrY=!Mg_(zbC&^2|8h~iF15P9ItssPEBz@6qB~t$8G4$BfR|$E$#NxTAO$i}af2TEhTk2DEFSLB~*px5ug|g|UqNj!<-*lH| zd%}1M^H?2#I@lEbu>-g5T8k#RzHs0ge#b58CWCDV_-g!Y6=h>%eqg}9VMH-*eRxzB z+x$=^h1vxZ+QVd3gvV_HeaT4=DSyqsoBN$T#H7>O>dGyc^W`_@nCf3(;g`nb3a3`W zyWh!R7aj$~IscUC1-k;BI>LS_Ns9SPNv6j*L13|%o4Hi6zvLAgkM~&qP5V99Bf*X+ zDw=UIp6a`XI_=HZe~D7If*o=brRp_Idwf^#6}|AX>qi;e=f4hTy;qUpZnxQ_R8~qH zJ$ui#INl00Gp7ltnu^tLYo8hRdVl1G6^C6oefgI>hctISV*uhgmZG0EKT zgxO*L>1t)#V7=ZXa9#-$>J|hka9eZ)z@K-7UqQn35(Y2qNh7aoN-<4f=&<)$pJWQ} zr_@9tn<|}YllJlLc5Q~~paLL#;l_y2kKF}4ejv7NcW!GMfGH}Q6m+6@VVe{rx8Y*` zwzCPOYAiX^N_K_Xf6d8_<76GbTU3@0LmDME1tj_>>|E_YrcFZzIH;~PKKl;Zo#0EW zjGw@H5i=H+L48BJSxcl(x6HdneQDn);U;Ibtlj``petXa5&hvuz}FI#9Kv(m79|Nf zh&{1x$3>SH{1@{8FC^Al@YbmM?ssYWf%DoQyo*6-%-r6i14HCV6pA5hc8gvCXD>=)TDbItq3s(rcXSO*bIJ}S_fwuokceQ- zB|I6hb4w<{PFUJ8A_&o=4v6o0B*<14(g+h?mjIO{rCn*OvOSa|^~b#8z8zm>~^(MEU@WJa3t z^mxIi_a9M9i~qSNbco#sqxF!*=se}k`YjMKozISe&3%o%u!ChNoXjjF7cSI4C zQ74!)d4V_=&NfLATj)z%aIsvxiiS&Rv^-T=cy4#RG(L3Fev5X^hBoa&dDv_oz>i5S z!X_j!AUg0n14KfT^aVzzx*(Rs-HMbpBdK<;jKe%1{?TOSi6@8$g!Z3d-sRl`#i1%7 z5%_oDE5X@DsJH3D(N=e=!$u8Ws$?pOp_Z*EA^e@wPGz$d^M72y4fX^WhFn$KH$p{4eBC}W7@mJ1F8J&KyU(5J+9Fr=xl%o>= z+E3%yPw|d#FSMF9E`1j07cc;K)j&CDH)=-B^@>!iTGAuJ=R9`2+MEs8mqj34caO%j=vU%Mw#C1uI)wKgP>aAB0ezo|4sUa`UL<1gXE9tD zTq7{)=Hy9jbC;XicD6tKPBQZvgcg7~20vMp!UF<}8sBUDgjjixgvZ8XUPrA=2=!VY z<`oWEHl!FQQhbQN_1uiH!`{&XL(iv-| zX$plo&Z7y^avW_s81QJlghy^yr<|u|XOo#t4xH|vUqKp1x!S{pY?GG$>D4=eCXUZal(y2!ZR-1b*RJi5OQ;7k z3v@XIp0=s%?1DW9`2o)G4pv(~x3Z8&AG^SI4 z%T!XeU3t?cR7rf`r_Oei*s&Vie(d0`q| znKGpuXD`EU<8nso)v^Ep`)O*`$6xEXd$9_$=GTvk7zLMq$zRjYoHlI3jIC=JC|woB`{SaYorj9gP2b*V`X!0yV5J{EYkXL)<~AAzoIjp zo$@F9VNH1s>8j?V*stZh9$)PUwkDbVzqQ8NDrg9F;(pFm$AxMg$Q+m+ zP&An8kn91y*agq;v7^i_h=t&8WlYY67av{(uV%MZ8Bn*~=StjDP``GYtqN104(z(@ z_l@taOoDgwf;l9W|iiI~nquz3dBy6>O7L7Rk~Kc=xUYnEa5L5!A7xiZ-B! zFxbZXc^|_gKVBhfmL}xkLW!I&cC*6jn`yVnc@_zNM~|5k>|q zYdGHRqkvPffF`owM_LP&PiSs%+)k2Cln3yO`r(&4S1$j=Y{r&Cg(%T=9Dk-@3 zth%3z{LL1W6>ht=+&h|YH!pjMffKhqK}u^l=Q7^YU(*w4Z1ZZe3)7anAH63eC4Caw zGM9T2GvYcc67-pF64ji05c36dm%Lq!=eOXuVXwm>Wi{GYP5CUn;VdX?J0Z3E!OpAT z2`zF8z~jgbme8nVOq6|(32WAl`S6h4!k5;)8^-%v3kRC8MsO>Dyjx8p!kiTW6w;J z9`vU1#K#Nj^rE{LEqJVU14gMgzaI@-z{Kx;vEg(O47u|QccAocjVVIkXK42KV$w{gr<%RYSEtG1Z_ukM~o$h z$rb^e0-QuS2Pt2EVr*5OdY-X(kOdW-^U+6Cs(zl`??BE(+MaCR7pp(cWo-~ z8Gg$w+UF!eB;R(Pm<1;E>M53;QO!Iod5u@NUG7~LYB@IeWummpqbgrs)5UQU)o@~# z`~BEo{V@I=z-U;h_>ttXZu`|&F~4RCCi`N4d-6IUAUoir1Q<>y$o1{2ceA3v6LcE$ zkhoGvRyh>gA!Pg8`hBd_xkjr2;NQnZb6)+en*F1go`XA;1vI^dHR&vBLY$WOtETe> zT0UgIDQmG75FaM2(yX%9?SQYDEAn5aWS4P3o86|p@-=y%`^>T$8*KDdw*=4LUL9{F zx=4fZOPl~+6tHmZ6QTk%F>BR7aO1rbQ@yR#lDC~Bm4Z2AFM?~gr1AWOHSR5dcyhLK z5H1>Yzl;Qlk;Wv+!+=xmVUDJm>KB3ORTY5Md;?^werhOf3-WGzoCM9E`!z?q_M~yr ztw~L+1$S?h`^iX!BD^O-m$M#X_|f-^q5cpzQz(Ilr(clcvPoO>N0`;@$rQv6FBKWxEECxRxAFLdO}7sj*l=N35u+b| z&!Z#!u%E`1LKAPpZyhhTDFN^)!Wu+glBPh=Kx)0oRQ>*y{-_iHk4y#@Py!5e&X7_K z1HM)WCR#ZHk!F!n*<3e>b`hvy6Oq?C&IPzi7>4#9p7J77;wGXs)EeME^B|frPlz0C z8W4uC@+@Mr9ZJMJ!vd4e3$nIXsW$=i=YWj(lBp*EN`5B2NF_f@st#ZM}A2>Z$Z0z&KY-DM=>EKss`#dCn+h?tiEf>5BF zB1K>^Vu#=xTEao~1la3lh>wC|{x};BbLjuPul;Yk(`lx@HnXD074X6T0;<)B`E2~P zOHPp1$bCOXe-*GEA9nMdG9-Y$9$)2mKN>RvcH+OS_lME|?j|R&*Ixw7{&xj_bLB@{ zxr_Y*ltGtQLvE6G7lJmU3sUc78BZs-!$Ubt%7o7S1oTrg7umJmT?%-~i6 zz!5lUm<0L3z{;TNc^BHFB`sq%a>H$V6(jclAHTYG*P5VypHj8BsIw!zTZ-zbuKr$5 zr~|d+8WI&kDgj)hFpO<*svQyhfaikJ`i5R$co+lJvY;mK;_~W>W_{*X$4KU(-1>0K z%&tOR;J-{QzS`YfQD3*Yep-nDo2amIXb=4e2Tf4SMBFHp`i@>%cGROuY^K2Wi%kd- z2JhXG%C&;o{Vj)NKxwb4NumW+0q>jxeMO$5I&K18x*gkPGV?j^<)YP*K*8iF?iMV| zd&-_KDX2U0^o}{_2sQHqWZd>FQ2_bDTdwRE(h2!}dT$6@DBlI|L0u?;U!h44Z=1<8 z25KYi8`3~>rJnzQcS4b44YvXyO)KL^mf10IF3K@*^PPmVzxmZXXlmbZ3}?k2N2r@- zrCpQtvc|NzMNdjM0d8}5kuxOPjpd`zqnr_^^Z7CdN$ZO4Ig)sKI!w-#UX1_qQb+qTYoxe z$K$YZJM$0-B`UDnZpA_VB$n@8la5t6(N<5D%)Md~+*u!V7*k&7(GwV~vq4UzP0PXr ziEGh5GmSiZfcT7&CiChfZdI~#eSYaMU4IiQ!f-p$TA3L0vAT~iYZ2=@*av9x6u;$M zsuZL1B)mfpx(zw6E6F}urZzU60-k;}eUcfv$GmHBhNd>8&P#y{NNbeEwf6}=F4cXo zp(BYr9M_qrpzd{_(6na=6532sJvzX z>}mQ>eAAIioHIB10|m{|f?(0}Kl_DVc`YJ3w$XbV%K8pmB^@c}@@Pdi_@_>sb=9?C zrWZ_tjX)PMJ0Xw!|tlBClTlDXG#YIe5D|3h?r9rjeMu6Wmq7?VmX9<8NaaF~7UuG!-Zt zVQou)bU0)>3*|I^czWORz%n!Z;Ttw1?Q17xVEy(fD z_IdUJnTzcKkltFr2+OmbpV#nr@Nu~H_uin~dxSDjC;oKw)9-1yoctR(V};qJid&DP z!&MyDhW%*3fjuZE{fRdZvnZf`<5t{;fMM6<^goN*4jtACuT=_};udiS#EvaO-UjNl z9O@D*s!t`X{L_aGccPN;@(pir)-IG2-i5zTSb(-(aNQALbl+lC^*^@uiix9aa5&M~ zi3)Ao9E*}+bg4a+ut}c8Y{1Ul#(70Zynea(qr!5=kIwO9p;l3+h6>qLyLW;aq3zKN z0F6#ICu2NVqy;#ebq5a`-HLfFd|+3;pZv=Tbl7`!YC7AMONMRAqS6mB9xgCy;^nFgkln zGfp6-mA9m_q*gA`TDgPwRQChLGy9k!%tSZ&)gb&F#dXf5UcvHjg!*Vucd{5NNk)H^ zr$fLa5z5NwIPx6>6q#sJu2m6c$LdG__;+kZ(G@?@DoLt_QH4C3pKKB#a0h~W7<-bI z@;=0I!rwnObx0-RyMSp@*o9YLw1#kobbvx(p9Z?%I7du|!Drqt#QlRE&}zQ*8ffDD zD)A#Tf7D4={VMr)ZP+k5m?Ud(q~22`OJBMTfJ+?_n2atG*WK4be-2zk>!wd)_L-km zvAa5(=M8TS;b}@Fu`r)@A00bSVdG5p3%7B(6a$j1zxh*S=c5(YJgWBPUK$b zPEJp0-9|`24Xi+!%kud;eHB(mrrW-Wemc-vNR5Fdy|$9t>uMmOHKdW6e!*Vz3qvv< z)m66}23R`rATuKUAV3|NGY%9NfYl`|gxCZYdv1g*c6h>)^%23I!OIo(-biVi^f8*+uyMYY6%dU;Ig+38BS*qOO<V1E;?B>`5G(`Y<{OmZaL&ETYLvf(6Y>Q&->bQ>`0bc$l|7S#e zDQ~)v9#F`W+hF=HlSyDTT(QJ$c3AIN1@4IYH8+Jp9(piLh8M5@%ar*7)r`OCh7*A$ z>W3b|ZxXnNxrbs9OQYc)Bybz2s|+mB_N`i6)?MI`MRPUn0Xf@fAhZ6_Pb(H60xb_y z0iO)?dl;6#RmLM~1se@05BdR@Z-aG^tBKMd{MaC^lWcVu6P@}aU~lZE5zlB}iHz?> zup^tW>3)BNhu2N*!M~0?<3y&;6UYqc5`O+GuM^CZr(UOIrZijT?e^B-<9~t`s{BAd z&TNkTYW=IIdfR{t0*`b)Ni|%2Z-2LX;SRdAWc@?{8jYAo3$hL$Uf7mnW$nMLcT33s ziQ|RFe#kjIX_C}{V6e~^vkQ8vYB|EU7cQB;h!hAP{SE$78c0r|f5PA$Y-~Hs%IaLK z9#{Lu^x5tGtqRU(SrWr23dN~Fx|CzWx$(rN~5Lxh&HkLxgZM^36rArahJJ!`H#m& zh1P;@x8E^vvQUB3`8N^u2Y(e&0eHD8U>p2fyucHZ)%;4zqCweum7itAm*>gu$M155 zz0VMSFrzH@pcHX%h@6eqd@=8GtA`fa@yL;_B7^rSqCR}&l0)XVBTOO?l)Fv(wWG@G zIjtOJ?oYB4nu^Bh#x-BxXStyEsN%&N! z*qH=9n4FCA2q0-CV;woyH-mpNUV<`2e>kc5dAyZ$0>y7`z+4utPOnnD)*&T)JujG_ zn=TVgM?&e(QAfSDWkkK9!_WUR?WUg0z6lymxN|S$yn-ZGRS=u|^fw?(!oADwdF^d`jAs^#oGDiLVzNr=mKp;e_HKTvPM-J?h`T#J&EV(4B&h+XizpxC#iZb;`%vE9- z$3>Y4(gFavx3dp7tGSP!X1;}zKwb5_=Fs~)0vz%vhXUO^sFug2SpI>Be|ntJxsX2gS6_DBR~aLG3^H^haXj58IN3b;TpfWpwR$#?-#(*YJ<}4a zFVVYFUjAU}NqT+a>Js?QPf1M^Xi^nvD7PjAe==(F>ilFNnyXsZ^C&t6?iCfAedqgX zl&3}{m^Z;*#g{DlC4lRx|D&kM;cNLJ@*D$P zhT*4wogJBIAKiJk=MU8=JbfJMcPxJn$$Ux!Y8BIg+;b|vd_1^{cluSv*mWy$xOE_8 zT!YWBH2CJan*YqDAx+)A(rK2^ok&l;@Fv;G&s8k{*_Pb!ss-9%rPQ9)WhiV*qKLSS zTT{5d;LMxwpy1y1_q+RNYyfENbmt675IRm>YK4&9J!J}umTkP%KhZPrc9OCh#N71S7*8$N?phTS z6^o|+p6&E~!s!MH2>n|SDEQ4_Uh3G6=Gpi@Y6wjS^bPYQ=E873YvZ+c74*JxP2BCA zbmAC5t%EKRaGaDxw*^-TpsfSTgN1Gz2eR{s{r79Vc3x+{JXA6oI;(hs=A}`IQW<24Hn&|~ zYEQ}y(hXb3oeHpG|9y{UNYah>hfwwK&AiZRM>A@T+g;hX)zg?${qj#*rVzij$iZ_W z4^VnPF+QMYv_&fv+K|GX6-ffMWjDevjLL^{OrFnh-9HYj+HG9V96k1@K7kKduC{}? zI{k}g{L|ptKMkuCxdFVaQ~u-$RSzf){miylay&)Pq=TQ)evqy`+Wj85g6sIa_Nd*I zcZ^&^41xlEIVg!l(fQKGSKqVOJ(LGznC|sw3eW`{~WugmI}A4bZ~$mCkWdx zYxz%l-JDXX(u4z=fjT`0r({XHMDg(`1gD4`;A_i5A_cv}`B86~Jx=Tz;P$Z9cEYSI zNu=$N-kJh|81aZC^;wJ)s^N3c>%yd?wzODvp3wD^>n<*hYfz@HxuXH0wV(CiW_8wD zQdpgvqw|e~jrFQKVoq^2!epk?I$P%gECg8;0|bWx8=!0c-`kZIJpjlqE}DQp9H^Xk zJ8KQgSp6dBOHTfwHaaqK#p({PZ_V_sL@)A znE$nNu}SUIK6|}NukUs|i8OVY5!CrfDK{e)8wiw)#7}kICu*Plr3lExE1WY}6#pAw zhFpsHhp8k=64-%A)1yC!LzZC-ijssz`W&Zp=1S>Na%HB?^B|_ zP5yLGRYGOXUzAo`J zs$IaKTO+_vQwJC0Ooe~-o!PI+moLh%q8~hxX^2){TP4?*5eM`8Hd>;fVEP=zx%Z?tEgCGr?>sPwDiz-pK|raxujm&#ErDY5Cj<-tY2o zje{=hE`Ye%2$!ESl55biheJ-%9=ns9HskUkkLyG>|nZRlw<79U{c z@@z@(lxf_Y<^Dc@QL@bS%-HvR_2n`p9}Bnd`pl?(r?Qq%_O*%RG?8U;p`EiE?~bGJ z_s7UFoCF<^`2rJ80}JW=Y^JVM-^5Juzbrk)^w}6yxcUo|!W^+H624+THCd=O zLa3RZqX+EoF$D6%3%B1&*;lOvSfpHe{lJ?Z_3T05rY|Glos;8ac`&-Ce@2Px5Z?%n z2~e*i?ntx1eriVR)tt5ptmI2=H%v@FmB2wcA+(R}Z3(&fS-M639n2ac)4B$|Z1ZGU zc?Xu^=*~=mOV0~TjghI2TLk;y{G6b>B+clv@f5#SGuic&(6k8Yr_WkON@3tH*IAXGgaT2HikrOi;&7Ag6C@PtPzxZIx>pMrfW5 z5?z^rzYprR)?X~a;+*HQjW(Y&eSM~!l(O^HF4RJ1Jqy4rN^CS{a8yK{1tIyhguVTy zjfdX@qq4Tmfln!JPR+Hyr6?N>&c!3|ljlK}y?Q)5AQp+YuK6YoZvvRNObf>;R^*Sw z-kqFofsBUv+3mrLW-mI{T0zZt^V@G(q3Ph?yIbAPg^tFs{&r5pTZ**q@p95{Udl(v zYrAyUMqzfZkbeD^HlX|kdfCGHNaDx%I=NQ$)$59?YGe;=R8z*>E|DO>Y~V$znLQ7q zX;B}RiuYslFhbObTb?XRR+B59qh0 z`tYBI+@#@+^n7048EG;+DOTG^@Y}PJz)SaL!e2$lDRADiPK=cUD4TV^_X&R^Rh_9C zYlt$lXwXLnA07E(^i}ZWSea^ITWdDungcVBQ0V9N&dyRn1By6z>p#n8dK^FkxPwBF zCFYamNZ5{EahE6B!=uHfQNcg`lZAbExIMb<#$Q72lDNq>BuGmy+(p4?aQ9X{w&`W$ z%H6YXE_Ww^LrQDSto{RG3WL>#tne`f{JP%)+s4dR{)CQh=COL3{>i z1orcY1hA(JW1tn$-*HqvGt6KKCtdDjlt1pE!#GHVK#cq`llC}?oH7uOA7`czJ^_rE z%&|`}n}>9B#Bd$r^K;aN${d4ZW~eJLLtmh>2eq}uy{APKqdoy5Zm`Hv`D_VzKF?PD zJGmlNjKPE?q2m!vI;sJ4d&5s@_aHRq=6mofn-}~ZW)yf4j@TGn*?^jrnRH@46fpMn~gF$P?B*P%+9b}h8y8}$VI-(WxM9T;5jV*EZE4oq&sH%EcX-GQ$+ zqP8zVXtb2s{+6{^n@W&$gG2jq39G`N+f|V#*3mE6evC$>okzF*k$)}J>%u8&iB&Ao zJBRUyzRU8yf!oepeR>1g6HIUSMI{rW(vkMXN-Ke z>j%#@*9cbnfFp&e<%+aB4VP->$Ev<}xQ&%dCIw4a87!?^4#(xmv+0^1ha8q@UyMMK z(aJq8$MB;D+e>H)??EA2C{BYi9?0NQuD-`+66J!fjTe3Ue$>mn|0@nE!|z?9cH0;f zR(YQ7$W|S-%hHq(WVdO>>$OA7%feCz|7CihpPra_fQZk~UTc7?_|)pHjaC@WeD$&* zur5DXEDz!=K31^Rhq)@1hMN99-ly**eQj8q;onjH{i~l9R<++$`&S{kWdCkUA@#Sk zJEEWK;5-uHur$Y^RbZ~LGZ!fY4!FLPPuqto=yI!$9ksYcLgv_g`YSCLmR!X?BRiE( zKx@unmFjO{J9^K8x;DMW4h1fLNiwBN2)YPrWLV`%)K`#v)0Sd+q__Ay@oYQ`KV9dM z`>B6M$j!xFHSdXP63Oy{Ju7-!efEp}tOpxTG5Nj146ZVN&gs+2!Qx0V{5$`nvH5Gz!-sExSsfHc+Ks8-L!q-q`ZGJ8GzCMLzfEp_ZJSV>WjB zdcsiKx4r5nOck6Tw!eVbHl24-Xl6Vdeoy0Gj8&hwcR+`Csr@pDV@l#?QDh2gjY)W9 zo3sqAFxY}FLMM(40f~kxs^)k1R?Cftt3C~l^C!y&YJ7qdo3=Kp%~J5LpUWu@guz1^ zEjCyGnfj1&NA3DXE!@`OlYH{Xjg!}TALpE?5jaM*Q2PV*3?#I{=G}|ggfVYA{qP4EF8n~R*Ofp zt1Z?k!UDsq2r_E^LAj688~nl6fLjN>M!Oyf`2n=TjF15Ii}4_5GE zm1P-v;SKO#jNuEQd4s4Y;FPqB>aU<*PyR{>7I+4pKqlQWM2F225Q^kSod&m@ly7lR zM0P)qGDrGo8m@>xdLK?-+?qRKA&jak5QdvGIY)f%UYM|R5ozkDifdy|16I~y;uyqI z>4+57C4z-POSZYx7uI};5Ou&1fXcXNU7@tiZb04WTQzPSu6-ag5y+38l-w3OMx|y- z)VV;+QXPe*h2zW8-K3%%$;BKqY{}n{6sC&@UkRM|aJ~h8 z!2{02u@#0va>Qw;I!ni0QBQERs4(b@!5D5Vdr<3S_XNZ$zzK&EFU>GNc9i-Um$U;q zjboXHZCXT)aZMI0=m>Eni|iOs{4hW>ljQQ};fI(~#w9Dv2ONtNZ@u`r(cvxQ_0S5q zRU`&1+pZrgJwwyWX)u3Vtqe=oL)RHcd8Pzv*wCrhm&bw>h%(Z@*2oWLHy*^6>#u$Z zo?<5aBw0vMwVdzz)nt{u>jbzWzv9$uO0P4Fg?khGZ39Qm_|Q?ArW)wcqnsnRlK~+2 zWvh~w!b1OgeK0n`wt+UK2Jq)~h}dmz2a)=*!ko=1ohXfCtX<;pscHcZp~|3qQp$o} z|3{y0w8WqKn(e*|eUJW}y&QbuCgHcEWz6JTn%`v=ExCIF=DxRUrKdP`uq5!O3IWd> zqi^bC6Aa)$t@O&z@Q0jNc<*8_+7i|XYyFyv1uNz{i}nd6`UFR-Ov%Y@Nhy?VN1HD< z!S)J467zn##mnJNvVuSa027u_MiIzVQ=rV~kKOQ;FG_}q)`-R?Jey*sXp@*1)06! zQ8iXxtHV*ddI`)W4B4psiu0-38OQwLU{~TzNIzP{ThTb&37Oo#;u-b{GyI7gCY(@( zwrfM~z%aoGR+FI7TWbKVc?nDrSNLSq-F~8899>x{p&8qMl=|?@@qNr!IV06}Oci3j zki1Z@wqWsK|6YnN>Yt}tCy>^YtFKU^4e4?E=64k6PW{}9QE@UqZHB2sZzG4jT(~wt zObC0c{%Cib4G6^SL^|Ai)=gd|o?2Zyf9KEiY)hV2L4V5BO$C%fz=JS1ZkkwE6s|1?2a4d2`MqzkTbL9U#a8UhcF}9` zk3)cBTg}F4|)Q6%iZKi3*B} z$VGb1MFa$dC`d0+ks6Bho+v0NEdm14MWhKK^iUI!5;{^t550ww011JFeDB=%#&~~c zoIOrP&dJ_u&AEQ_2hM3o^+iEAB{qlKnDX&J_{Rt zT931K{q~2pjyqR!3?GG1)%l8XY6;L_s6-}v_&nkx>q^~q1rgcN>U(?DD>Y>jZ0ZwT zqH6{|>eBSvT$oQ04f9(@!U)Z^y<34^RvC+{kG;pRT9MYN4*iSJC-62Rk7GGK$u6&R z)*%zMGPJ_ZZ+6BC6wj(&c|)!)(wutiZaP}vX4WMk^Y@Qgj;YHhOPBkWchEkwQy5<& z+D_hy9}Zo$)`Y3n@LHfF zq1xvDSXG?B$mTRuv&(hg`*x1QqR7v>>`M)uEX%ECQq;bONc(ZPVEg%P?X^FRy}8yl zB8`ON$l_2#ki(9jV|!k8Tdnn;?G!@=-s^`ID@$)zzn{)fXgPuosP=vJIIB4ReYNz& z4gcm3$N4y?V03g!**fhKP*^$YAJ1mL7CHHYjjQiNm*VphTW0cwpPsh+-vBfQ14E&}Ou972i3TO^|Sg}I6tnm=!^7!5~UlBFTegAY0D3qR(v%`S%fG;`@ zd@03n`1MR(w6)>lf#2Y2vK=$h2=;?6N=BN}F%a)95-9vE=~Yjf+IWem&ZhZBO%vrzx3GRFc;0_%xrjh-AIwYU(It8E1hj#YbN%z6~mJm@D>YJa))Je zxBBEjr$$l~5`nZ{1R0Sa$S=D6nm4$W`_9xCA!KmbglxWko^H}Pi+a& zqOE>A3Akt!$Ksp=F1qgoaK%7Z@~mqr-S!!$frSH<$3NGROeI}+5d+r{_OHRK)9@t- zEe@!EdH{=X&}te!uJf!gEFZi{4z|F;feC0OYg3%}*a(gd_d`YCPzA)ys85`^dh?25c0SAE?+x4Om#mtfpBczuYPu>rCUlqi`2459Fk^-2ALr1p+ zb&{uE#HRk7EaB$rDox`H`uz(kF~i^Qxf~Q%A8(IM)nz>bTbgfSUD6QT1Go1RBs6QZ z#q2kh3nJZxUR9|faF(ia76uHoH^})KhLfi|W(-x(g&a!gY31c&zC#eZ$1r5nu+%JI zM#Ci$ARH#4$=>}X!JjJ6NNn8Sz49~Dc^;O+d~ZN-Ht3CM>>lv+Z?KomjCL> zKDQx~^#&nrg8#T3&OK}83n;otd5-hzKmNL-n4SL5HgpE?d_{SYg}OWR;otqqj`@Fjt&dtNydmcHj@M z{+PZsf&gJv+YYO$6|I@Y&rHr(waPl)B`N5w6n*+u@1kX>>kG*AgOK#_;U=XyF70eQU zd={R;_U@djH#8euh2Hd7K!juN9LZxwm|!K4!|09IOPy!=rcbCq)aYtoN`-KOLcX^l z*Q$ekAbskjuIcsOcOGYKdblO>uzkh*37gE(IMM=WGjKi|ISZ<#=(IFYvAbmVMl}`J zx+?HyWew!r5$%7Pjc; z2I%#Oq?NS6wQ-4YT8jui9159a>X6O0vVZ90F`rjgkO?uOFwf2PiBU(Uk-id(7 z4okx4?c6JUKUxJQSLq@i|6D)%WCWfwnFoUquef-5d=K?BPB)>ApX<4}Q(!oQ z;7otzVjLl#0b6&h+!>~nAMt(ppnHqmQuOO(&CYAVgyq!@OY=ic+IRYE*c>iaxhBt1 zpaXlOCTx9Bn=M{H7laR|-l+r3TeM=&MNT<)ja20zcb;;FA$@GIExRfv&E+@V+3~HU z=-#7}owkp2aT)PDQ90xl2l7A^%6)0P=XBK4DZ*(1#z@4jt`MB(P!8?#;HW{`{lo&! z9OoR6wmJumveUgT@237Q-#*Ww&I0J%G>QRwLv=-PSn*_dO5=HBeXw4>>(Ea+&q z4KQ#oEDMUr=1|q~M!Q^|u$r{(=oWmid;J+(l#<;pZGH28WE=vvrB4eVrAl%`A{k)K zbVwa1yQc0t5@*GASI@n>bDmUmq9}Q5FShu0joL4?|8XqBao|$GD*m3Y!{1ieo37jK zgDMFkx*dvQHD{aAdNnqWV^*V!ut%F!%pCxvN?t^wO*8)S$x63yr;?WG{;ID{^`ntV zhCyljB=&^8dB3=mK*Zx#n~_3Qw4nHkDWn@4F^UC+T%=#Of?z8Fziatf_Gf+K{DP4; zlawzH%c16MpmW4FPF-2WeG6HBxqG6g4*E5fx5xe2Z-BnXX{)<*SF6>R!ie(aCK`^$jsszbH2`|BL@5YQl@tnM6gQ_wG-TY$Z z!)Et``OOEIc|0RdSr>s99N8A1x7_AO^K^jKX}a(Jv^775Xly(!;f^x42{)&pc=h5gG74l&_K{xyRm^Czm%R9<=x$?~zM?E&*L!WcnbrG1BF6bRn)DrncmY||r zYcvgqB)16Lt$Z5$r+5H+GUHYVUt$|kK-Tk7`)yQA#I_r%;p1s!Uk$PYr)l@%f+9L) z!DYkbCgisn;M|%=*34V_$Lh_zE!?L2>*+MF`{2~&cJ$wTfM1!>H;>Gk`gI){F`-lEp0694Dm~&l#}eSWjmOl zs`+{8MMuEtIq$A*rNb5QnO^Tbt36^b3U`u70y@I&dvu6hXgT2JTP`4Lb#EZ-ckL~bY7Xr$ZXVg8LT{48 zTlyIHnKGlQ&I@-mYpj2fT*|SGv!B)p(!LE;OuHEpBp_%gx#aE*Gs=V z{>3X=l~@n#xDkJs@?t(IO^~ja5K<2F6Kx~;e}|}y$Tr!a+#jrBYGbwnmL8WBtigyl zd*JE3!o2^D&S)E~j!VxIRm(8Cpc^d1u617d{keY6qf-_K*%+y)D$-kx(0p5ivxj%m zX63)aRbXALdm#vlW4p?L%F9vFTKk26Y)meB4*tsqKUwFf!)vSF?X0CX>DCbFgi&!K zv>K;WX}}UL#ur5u-H(eCKEe{o2+`@*`MX0u z%M}6IA!ua}F~g+ke1#7|1<>j@XEcAV`*}IT`GNq1Alk#MJ0DiVB7 z4*kXU4ltz6P!g}NReb&~N5@E4l}*~V>nBrkMAf^b6$ZQJZQc8hS8;tLaZQahOg%Ql z(?ZErSs?OeyukwJSN7b(<6+)+zc1=M))7{wt`AZNirb&J;%5<~M5w^`)h`7e0DjKGE5KPDn((NmYM74)XkNWjm1{F}JPHabsdi&|^i(`5GBAOfqqYa* zzDOP4_7Al>#D4ArtS^#+b6H;ihzfVu+bd5eY@ntf_~iF)5Je1TvwQ6N6_9-aYoAR>D9%d1CU-FEPq=VEHD-M z2Xp3~05J}Jtd}KR`>I(E*F!k?<}Ir5!e3^g>d%(#=#6lvV=gyyy5GMz8O;Wv*Lw!p zt-R;;9UcbnkSyvydW(-vM`J9zcp^;_;UeYS%Ya*EsxYg6}k94KeHXX{2X zP`C%x0|<(?s6A+EtU>C7z3rxSFcBOJt)Be1gw#nR_5r5FItTNgM`M$F4F`{sJKEEC z+!gUCXN_jL#Dbu)D%IZvH}%yAJ^v{6tKFYz%$78YEpzb{J$VM^7h~a>H(NE5o}qyH zS8S%kIVw=4azO8k;e5A~#Ikx)s2vV4Dx1Vbe3vomdlOIoHx{6J%{QH z#9NXn%wZXz9TFF{)~K{h_cjXK7?O*7Dx@4wxUo`Eq@N}!b3Wr|2_J;v0PbyNTNzRKsN?%ofC;nNOfs+yrRB)h>L zh)xF$HCp-{X8sD4bJ#}B@H84zE;8CI6Q^Bx2`L9x>>dr=a{$K%`ERZ=fT_<@!wl(U zHM>@sCF^yC0H6EILK*GmU4t`yI6xy&;3(rlEEMltQGUYBoy z-bj$7&cMe-&K;LFDtXM~VoZw*U@vmwdfH9(%NGHgvf2xF>1N^c44~_<)b={KA9VN# z0KB9uZul}3U(WtbVd(*ra=df^M6x-wU*l}ZP zX;mnEO_@*#0|Hq;!Bw1w>A7>*UzJ@R)!R%JnXS4iaYoG6z~ex%Ad%5|a20-2Zo%XI zGdZodgb?X>8r5U2uIH1Lm*mlwfk#yRERZJ=x!VHnrU8{jvgH4iwyqH_N$g@a#CR>%kGMX?F7DRm#Yp>H1l`X8Ge_qC9dxIOeu15M3Zk9`{> z!V0EV=yH~>=72V7JZ&i_@=q|#^jEGi84k;3_7zxNDYBHa&LLqEH*lgv>{a+AOOQTg zU$Bn5hB7HF`JN8GG*vo*N1e_fOE?W>nXP)I=rg*2NbA(hFq z^{&Ae2}$wjTr4t*b*f#IT9&J)LY?7isT)|4DCUd zFwoiCSy@erG@f1VtrKM9=X9%udpFZ&o!l(Saw4Tg)Qyk1J#F1VoFCc^M@5~fmT1zb zyI-icbj#3-Px`~bx)x~tYTq@gHnd|WZW7;tyV6&V!#+1Tg%$Z`ypMzriLMgQ)vqA04AC+#DAVq%VNpu@-ZNnSZ_*m`LlMQBF&$u-{ zn4Mp!Lw{6Psiw!0cXY=dOskrGy(h{jRW~)>f2HNKTv2^!@U&aTGdLgK6Pe+tClfvR zD-eLys9{*wq@pmT%YamT!)z%#Y8d`&oVtR033da6CV`ZDI3dmXg}dBYINtr^o~RPr z;#wW}6Wo|&mhbk0(rI^SHvJBz6wI#=h!IahIC%7=_^;LLP~T<=4zngggBnznas;W9%!9NCbV6zRG86yk-o+)ci_0C zJD;3Q`#7{yYUP(*=-gSBu?*K%iDapAFWN@D8E!NBNVD#rnbad@4qT7^_HNXX>v)`4 zkx1C7&`AQG_g4gU$p8sRJwqvM4`O^u1^6HQoba5wk%6w2Shv=RRp%ywIHm>J56H)Fu~Tc zf{(Nf%U|BWw1YxNG$QJ{zW_VxR^P*%tLNO76)nD>v>1*nQ3sk50q(+vsu=v&9`Y)l z_s9xs+2QanqER`V9wzbqIL58Cnj3j^;rX_R^_Ilt2@`(gdb=N@8WiheMT}wHsKQn! z$Vd2S;i_CaYhzDv3x=S>&dwDb$Po?Ga^t?;tjhIkP#LFqdXSV{ZyPVfWEgL!HDPxN zA6fs{tN~*Z7^A7K<0V&zdf))$0=dL@9tc9w2hRLIz**CThzHlburpF^0yewx8P6>H zHKz^w~Z;Qb#55ZW5J+pheuu=&ke6Ris9;K za2$38l!A8sSeL*%wRH*3*~Kc?#rM$Q28Ari(cFsiIQ{gZu5$uewfthM@7Yc#1hBot zxcxM@tg4U0CiW{`ueqce1Fukg2`!x2FZF20@u&|LSUVpX{9adf>mbVWc#B~amjV+m zaeDW&nb1n>eKzZy(EtxWJ5Y9Q(t1<`7mOf$$AT%LxX67aS;;%|?$;g6M$lJPJcI+E zj$Hm4pAg8pv--o@+f3?Vj$Qsk;+)621<7?Xe5>UUr*{-hdwTpWy@NOrv{HRhHdwCr zT^Znt9a{=ox+^M9C_ri7YEqRHR|2MCJdRi;NKJ0-{97f?MwYB|20 zvj^HbpmYmLO0h1hsC**cyt2W^x+Gua%=~_QCPY|qKsdT#gSrbHi(E@8fIMina8F7} zM~n`{t3RYyknnKX5jm@TNl%2zv)KtX@Cp39`Ivlyj$3uT$VeLcv!q>$x4dCMVYL+B z<7AcGO^JQ;_QJb)Ifunw$t6SORcyQWch_GSK59EZw@8U?Ut-uD)^)&U)UUF7jbLzg zWIJ4*at(f&yfxUKE359?cOWJlAO7``@*K5ay6?4RLAf>Hud&+KH+6<^8s%1j=cG*c zb*@atW+l`)pL$b4mHJ{zi#*UzqiF%Enq%8uXdE7&wvrxrb4utaBEynHo!-GwcdHRb zdw-loMSpDyjfO(n#uOxELTbekmJtr0eZYPf2nM_&dKj+L!tJZMoz}{&CwTa�+%{J4bcp~7@ubq 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 ZS2=0^r}3h@>1P;)1e0HJl(6x+|Jk!)inss( literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js new file mode 100644 index 0000000..cf05f1b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js @@ -0,0 +1,502 @@ +!function ($) { + + /* CHECKBOX PUBLIC CLASS DEFINITION + * ============================== */ + + var Checkbox = function (element, options) { + this.init(element, options); + } + + Checkbox.prototype = { + + constructor: Checkbox + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.checkbox.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.checkbox'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checked = $el.prop(ch) + , e = $.Event('toggle') + + if ($el.prop('disabled') == false) { + $parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.prop(ch, ch); + $el.trigger(e).trigger('change'); + } + } + + , setCheck: function (option) { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checkAction = option == 'check' ? true : false + , e = $.Event(option) + + $parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e).trigger('change'); + } + + } + + + /* CHECKBOX PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.checkbox + + $.fn.checkbox = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('checkbox') + , options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.checkbox.defaults = { + template: '' + } + + + /* CHECKBOX NO CONFLICT + * ================== */ + + $.fn.checkbox.noConflict = function () { + $.fn.checkbox = old; + return this; + } + + + /* CHECKBOX DATA-API + * =============== */ + + $(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) { + var $checkbox = $(e.target); + if (e.target.tagName != "A") { + e && e.preventDefault() && e.stopPropagation(); + if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox'); + $checkbox.find(':checkbox').checkbox('toggle'); + } + }); + + $(function () { + $('[data-toggle="checkbox"]').each(function () { + var $checkbox = $(this); + $checkbox.checkbox(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================= + * flatui-radio v0.0.3 + * ============================================================ */ + +!function ($) { + + /* RADIO PUBLIC CLASS DEFINITION + * ============================== */ + + var Radio = function (element, options) { + this.init(element, options); + } + + Radio.prototype = { + + constructor: Radio + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.radio.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.radio'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , checked = $el.prop(ch) + , $parent = $el.closest('.radio') + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]') + , e = $.Event('toggle') + + if ($el.prop(d) == false) { + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + if ($el.prop(d) == false) { + $parent.removeClass(ch) && $el.removeAttr(ch).trigger('change'); + } + }); + + if (checked == false) $parent.addClass(ch) && $el.prop(ch, true); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + } + + , setCheck: function (option) { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.radio') + , checkAction = option == 'check' ? true : false + , checked = $el.prop(ch) + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]') + , e = $.Event(option) + + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + $parent.removeClass(ch) && $el.removeAttr(ch); + }); + + $parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + + } + + + /* RADIO PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.radio + + $.fn.radio = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('radio') + , options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('radio', (data = new Radio(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.radio.defaults = { + template: '' + } + + + /* RADIO NO CONFLICT + * ================== */ + + $.fn.radio.noConflict = function () { + $.fn.radio = old; + return this; + } + + + /* RADIO DATA-API + * =============== */ + + $(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) { + var $radio = $(e.target); + e && e.preventDefault() && e.stopPropagation(); + if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio'); + $radio.find(':radio').radio('toggle'); + }); + + $(function () { + $('[data-toggle="radio"]').each(function () { + var $radio = $(this); + $radio.radio(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ + +!function ($) { + "use strict"; + + $.fn['bootstrapSwitch'] = function (method) { + var methods = { + init: function () { + return this.each(function () { + var $element = $(this) + , $div + , $switchLeft + , $switchRight + , $label + , myClasses = "" + , classes = $element.attr('class') + , color + , moving + , onLabel = "ON" + , offLabel = "OFF" + , icon = false; + + $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { + if (classes.indexOf(el) >= 0) + myClasses = el; + }); + + $element.addClass('has-switch'); + + if ($element.data('on') !== undefined) + color = "switch-" + $element.data('on'); + + if ($element.data('on-label') !== undefined) + onLabel = $element.data('on-label'); + + if ($element.data('off-label') !== undefined) + offLabel = $element.data('off-label'); + + if ($element.data('icon') !== undefined) + icon = $element.data('icon'); + + $switchLeft = $('') + .addClass("switch-left") + .addClass(myClasses) + .addClass(color) + .html(onLabel); + + color = ''; + if ($element.data('off') !== undefined) + color = "switch-" + $element.data('off'); + + $switchRight = $('') + .addClass("switch-right") + .addClass(myClasses) + .addClass(color) + .html(offLabel); + + $label = $('

    ')).parent().data('animated', false); + + if ($element.data('animated') !== false) + $div.addClass('switch-animate').data('animated', true); + + $div + .append($switchLeft) + .append($label) + .append($switchRight); + + $element.find('>div').addClass( + $element.find('input').is(':checked') ? 'switch-on' : 'switch-off' + ); + + if ($element.find('input').is(':disabled')) + $(this).addClass('deactivate'); + + var changeStatus = function ($this) { + $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click'); + }; + + $element.on('keydown', function (e) { + if (e.keyCode === 32) { + e.stopImmediatePropagation(); + e.preventDefault(); + changeStatus($(e.target).find('span:first')); + } + }); + + $switchLeft.on('click', function (e) { + changeStatus($(this)); + }); + + $switchRight.on('click', function (e) { + changeStatus($(this)); + }); + + $element.find('input').on('change', function (e) { + var $this = $(this) + , $element = $this.parent() + , thisState = $this.is(':checked') + , state = $element.is('.switch-off'); + + e.preventDefault(); + + $element.css('left', ''); + + if (state === thisState) { + + if (thisState) + $element.removeClass('switch-off').addClass('switch-on'); + else $element.removeClass('switch-on').addClass('switch-off'); + + if ($element.data('animated') !== false) + $element.addClass("switch-animate"); + + $element.parent().trigger('switch-change', {'el': $this, 'value': thisState}) + } + }); + + $element.find('label').on('mousedown touchstart', function (e) { + var $this = $(this); + moving = false; + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.closest('div').removeClass('switch-animate'); + + if ($this.closest('.has-switch').is('.deactivate')) + $this.unbind('click'); + else { + $this.on('mousemove touchmove', function (e) { + var $element = $(this).closest('.switch') + , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left + , percent = (relativeX / $element.width()) * 100 + , left = 25 + , right = 75; + + moving = true; + + if (percent < left) + percent = left; + else if (percent > right) + percent = right; + + $element.find('>div').css('left', (percent - right) + "%") + }); + + $this.on('click touchend', function (e) { + var $this = $(this) + , $target = $(e.target) + , $myCheckBox = $target.siblings('input'); + + e.stopImmediatePropagation(); + e.preventDefault(); + + $this.unbind('mouseleave'); + + if (moving) + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)); + else $myCheckBox.prop("checked", !$myCheckBox.is(":checked")); + + moving = false; + $myCheckBox.trigger('change'); + }); + + $this.on('mouseleave', function (e) { + var $this = $(this) + , $myCheckBox = $this.siblings('input'); + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.unbind('mouseleave'); + $this.trigger('mouseup'); + + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change'); + }); + + $this.on('mouseup', function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + + $(this).unbind('mousemove'); + }); + } + }); + } + ); + }, + toggleActivation: function () { + $(this).toggleClass('deactivate'); + }, + isActive: function () { + return !$(this).hasClass('deactivate'); + }, + setActive: function (active) { + if (active) + $(this).removeClass('deactivate'); + else $(this).addClass('deactivate'); + }, + toggleState: function (skipOnChange) { + var $input = $(this).find('input:checkbox'); + $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange); + }, + setState: function (value, skipOnChange) { + $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange); + }, + status: function () { + return $(this).find('input:checkbox').is(':checked'); + }, + destroy: function () { + var $div = $(this).find('div') + , $checkbox; + + $div.find(':not(input:checkbox)').remove(); + + $checkbox = $div.children(); + $checkbox.unwrap().unwrap(); + + $checkbox.unbind('change'); + + return $checkbox; + } + }; + + if (methods[method]) + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + else if (typeof method === 'object' || !method) + return methods.init.apply(this, arguments); + else + $.error('Method ' + method + ' does not exist!'); + }; +}(jQuery); + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-notify.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-notify.js new file mode 100644 index 0000000..f2f0c74 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-notify.js @@ -0,0 +1,404 @@ +/* + + + + Creative Tim Modifications + + Lines: 239, 240 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically + Line:242 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon. + + + + +*/ + + +/* +* Project: Bootstrap Notify = v3.1.5 +* Description: Turns standard Bootstrap alerts into "Growl-like" notifications. +* Author: Mouse0270 aka Robert McIntosh +* License: MIT License +* Website: https://github.com/mouse0270/bootstrap-growl +*/ + +/* global define:false, require: false, jQuery:false */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + // Create the defaults once + var defaults = { + element: 'body', + position: null, + type: "info", + allow_dismiss: true, + allow_duplicates: true, + newest_on_top: false, + showProgressbar: false, + placement: { + from: "top", + align: "right" + }, + offset: 20, + spacing: 10, + z_index: 1031, + delay: 5000, + timer: 1000, + url_target: '_blank', + mouse_over: null, + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + onShow: null, + onShown: null, + onClose: null, + onClosed: null, + icon_type: 'class', + template: '' + }; + + String.format = function () { + var str = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + str = str.replace(RegExp("\\{" + (i - 1) + "\\}", "gm"), arguments[i]); + } + return str; + }; + + function isDuplicateNotification(notification) { + var isDupe = false; + + $('[data-notify="container"]').each(function (i, el) { + var $el = $(el); + var title = $el.find('[data-notify="title"]').text().trim(); + var message = $el.find('[data-notify="message"]').html().trim(); + + // The input string might be different than the actual parsed HTML string! + // (
    vs
    for example) + // So we have to force-parse this as HTML here! + var isSameTitle = title === $("
    " + notification.settings.content.title + "
    ").html().trim(); + var isSameMsg = message === $("
    " + notification.settings.content.message + "
    ").html().trim(); + var isSameType = $el.hasClass('alert-' + notification.settings.type); + + if (isSameTitle && isSameMsg && isSameType) { + //we found the dupe. Set the var and stop checking. + isDupe = true; + } + return !isDupe; + }); + + return isDupe; + } + + function Notify(element, content, options) { + // Setup Content of Notify + var contentObj = { + content: { + message: typeof content === 'object' ? content.message : content, + title: content.title ? content.title : '', + icon: content.icon ? content.icon : '', + url: content.url ? content.url : '#', + target: content.target ? content.target : '-' + } + }; + + options = $.extend(true, {}, contentObj, options); + this.settings = $.extend(true, {}, defaults, options); + this._defaults = defaults; + if (this.settings.content.target === "-") { + this.settings.content.target = this.settings.url_target; + } + this.animations = { + start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart', + end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend' + }; + + if (typeof this.settings.offset === 'number') { + this.settings.offset = { + x: this.settings.offset, + y: this.settings.offset + }; + } + + //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing + if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) { + this.init(); + } + } + + $.extend(Notify.prototype, { + init: function () { + var self = this; + + this.buildNotify(); + if (this.settings.content.icon) { + this.setIcon(); + } + if (this.settings.content.url != "#") { + this.styleURL(); + } + this.styleDismiss(); + this.placement(); + this.bind(); + + this.notify = { + $ele: this.$ele, + update: function (command, update) { + var commands = {}; + if (typeof command === "string") { + commands[command] = update; + } else { + commands = command; + } + for (var cmd in commands) { + switch (cmd) { + case "type": + this.$ele.removeClass('alert-' + self.settings.type); + this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type); + self.settings.type = commands[cmd]; + this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]); + break; + case "icon": + var $icon = this.$ele.find('[data-notify="icon"]'); + if (self.settings.icon_type.toLowerCase() === 'class') { + $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]); + } else { + if (!$icon.is('img')) { + $icon.find('img'); + } + $icon.attr('src', commands[cmd]); + } + break; + case "progress": + var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100)); + this.$ele.data('notify-delay', newDelay); + this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%'); + break; + case "url": + this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]); + break; + case "target": + this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]); + break; + default: + this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]); + } + } + var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y); + self.reposition(posX); + }, + close: function () { + self.close(); + } + }; + + }, + buildNotify: function () { + var content = this.settings.content; + this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target)); + this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align); + if (!this.settings.allow_dismiss) { + this.$ele.find('[data-notify="dismiss"]').css('display', 'none'); + } + if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) { + this.$ele.find('[data-notify="progressbar"]').remove(); + } + }, + setIcon: function () { + + this.$ele.addClass('alert-with-icon'); + + if (this.settings.icon_type.toLowerCase() === 'class') { + this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon); + } else { + if (this.$ele.find('[data-notify="icon"]').is('img')) { + this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon); + } else { + this.$ele.find('[data-notify="icon"]').append('Notify Icon'); + } + } + }, + styleDismiss: function () { + this.$ele.find('[data-notify="dismiss"]').css({ + position: 'absolute', + right: '10px', + top: '50%', + marginTop: '-13px', + zIndex: this.settings.z_index + 2 + }); + }, + styleURL: function () { + this.$ele.find('[data-notify="url"]').css({ + backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)', + height: '100%', + left: 0, + position: 'absolute', + top: 0, + width: '100%', + zIndex: this.settings.z_index + 1 + }); + }, + placement: function () { + var self = this, + offsetAmt = this.settings.offset.y, + css = { + display: 'inline-block', + margin: '0px auto', + position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'), + transition: 'all .5s ease-in-out', + zIndex: this.settings.z_index + }, + hasAnimation = false, + settings = this.settings; + + $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { + offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing)); + }); + if (this.settings.newest_on_top === true) { + offsetAmt = this.settings.offset.y; + } + css[this.settings.placement.from] = offsetAmt + 'px'; + + switch (this.settings.placement.align) { + case "left": + case "right": + css[this.settings.placement.align] = this.settings.offset.x + 'px'; + break; + case "center": + css.left = 0; + css.right = 0; + break; + } + this.$ele.css(css).addClass(this.settings.animate.enter); + $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function (index, prefix) { + self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1; + }); + + $(this.settings.element).append(this.$ele); + + if (this.settings.newest_on_top === true) { + offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight(); + this.reposition(offsetAmt); + } + + if ($.isFunction(self.settings.onShow)) { + self.settings.onShow.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + } + }, 600); + }, + bind: function () { + var self = this; + + this.$ele.find('[data-notify="dismiss"]').on('click', function () { + self.close(); + }); + + this.$ele.mouseover(function () { + $(this).data('data-hover', "true"); + }).mouseout(function () { + $(this).data('data-hover', "false"); + }); + this.$ele.data('data-hover', "false"); + + if (this.settings.delay > 0) { + self.$ele.data('notify-delay', self.settings.delay); + var timer = setInterval(function () { + var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer; + if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") { + var percent = ((self.settings.delay - delay) / self.settings.delay) * 100; + self.$ele.data('notify-delay', delay); + self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%'); + } + if (delay <= -(self.settings.timer)) { + clearInterval(timer); + self.close(); + } + }, self.settings.timer); + } + }, + close: function () { + var self = this, + posX = parseInt(this.$ele.css(this.settings.placement.from)), + hasAnimation = false; + + this.$ele.data('closing', 'true').addClass(this.settings.animate.exit); + self.reposition(posX); + + if ($.isFunction(self.settings.onClose)) { + self.settings.onClose.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + $(this).remove(); + if ($.isFunction(self.settings.onClosed)) { + self.settings.onClosed.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + self.$ele.remove(); + if (self.settings.onClosed) { + self.settings.onClosed(self.$ele); + } + } + }, 600); + }, + reposition: function (posX) { + var self = this, + notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])', + $elements = this.$ele.nextAll(notifies); + if (this.settings.newest_on_top === true) { + $elements = this.$ele.prevAll(notifies); + } + $elements.each(function () { + $(this).css(self.settings.placement.from, posX); + posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight(); + }); + } + }); + + $.notify = function (content, options) { + var plugin = new Notify(this, content, options); + return plugin.notify; + }; + $.notifyDefaults = function (options) { + defaults = $.extend(true, {}, defaults, options); + return defaults; + }; + $.notifyClose = function (command) { + if (typeof command === "undefined" || command === "all") { + $('[data-notify]').find('[data-notify="dismiss"]').trigger('click'); + } else { + $('[data-notify-position="' + command + '"]').find('[data-notify="dismiss"]').trigger('click'); + } + }; + +})); diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-select.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-select.js new file mode 100644 index 0000000..a9ee735 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap-select.js @@ -0,0 +1,438 @@ +!function($) { + var Selectpicker = function(element, options, e) { + if (e ) { + e.stopPropagation(); + e.preventDefault(); + } + this.$element = $(element); + this.$newElement = null; + this.button = null; + + //Merge defaults, options and data-attributes to make our options + this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options); + + //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute + if(this.options.title==null) + this.options.title = this.$element.attr('title'); + + //Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.init(); + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function (e) { + var _this = this; + this.$element.hide(); + this.multiple = this.$element.prop('multiple'); + + + var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : ''; + var id = this.$element.attr('id'); + this.$element.after( this.createView() ); + this.$newElement = this.$element.next('.select'); + var select = this.$newElement; + var menu = this.$newElement.find('.dropdown-menu'); + var menuArrow = this.$newElement.find('.dropdown-arrow'); + var menuA = menu.find('li > a'); + var liHeight = select.addClass('open').find('.dropdown-menu li > a').outerHeight(); + select.removeClass('open'); + var divHeight = menu.find('li .divider').outerHeight(true); + var selectOffset_top = this.$newElement.offset().top; + var size = 0; + var menuHeight = 0; + var selectHeight = this.$newElement.outerHeight(); + this.button = this.$newElement.find('> button'); + if (id !== undefined) { + this.button.attr('id', id); + $('label[for="' + id + '"]').click(function(){ select.find('button#'+id).focus(); }) + } + for (var i = 0; i < classList.length; i++) { + if(classList[i] != 'selectpicker') { + this.$newElement.addClass(classList[i]); + } + } + //If we are multiple, then add the show-tick class by default + if(this.multiple) { + this.$newElement.addClass('select-multiple'); + } + this.button.addClass(this.options.style); + menu.addClass(this.options.menuStyle); + menuArrow.addClass(function() { + if (_this.options.menuStyle) { + return _this.options.menuStyle.replace('dropdown-', 'dropdown-arrow-'); + } + }); + this.checkDisabled(); + this.checkTabIndex(); + this.clickListener(); + var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width')); + if (this.options.size == 'auto') { + + // Creative Tim Changes: We changed the regular function made in bootstrap-select with this function so the getSize() will not be triggered one million times per second while you scroll. + + var getSize = debounce(function() { + var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop(); + var windowHeight = $(window).innerHeight(); + var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2; + var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras; + menuHeight = selectOffset_bot; + if (select.hasClass('dropup')) { + menuHeight = selectOffset_top_scroll - menuExtras; + } + //limit menuHeight to 300px to have a smooth transition with cubic bezier on dropdown + if(menuHeight >= 300){ + menuHeight = 300; + } + + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : liHeight * 3 + 'px'}); + + }, 50); + + getSize; + $(window).on('scroll', getSize); + $(window).on('resize', getSize); + + if (window.MutationObserver) { + new MutationObserver(getSize).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', getSize); + } + } else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) { + var optIndex = menu.find("li > *").filter(':not(.divider)').slice(0,this.options.size).last().parent().index(); + var divLength = menu.find("li").slice(0,optIndex + 1).find('.divider').length; + menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding; + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'scroll'}); + //console.log('sunt in if'); + } + + // Listen for updates to the DOM and re render... (Use Mutation Observer when availiable) + if (window.MutationObserver) { + new MutationObserver($.proxy(this.reloadLi, this)).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this)); + } + + this.render(); + }, + + createDropdown: function() { + var drop = + "
    " + + "" + + "" + + "" + + "
    "; + + return $(drop); + }, + + + createView: function() { + var $drop = this.createDropdown(); + var $li = this.createLi(); + $drop.find('ul').append($li); + return $drop; + }, + + reloadLi: function() { + //Remove all children. + this.destroyLi(); + //Re build + $li = this.createLi(); + this.$newElement.find('ul').append( $li ); + //render view + this.render(); + }, + + destroyLi:function() { + this.$newElement.find('li').remove(); + }, + + createLi: function() { + + var _this = this; + var _li = []; + var _liA = []; + var _liHtml = ''; + + this.$element.find('option').each(function(){ + _li.push($(this).text()); + }); + + this.$element.find('option').each(function(index) { + //Get the class and text for the option + var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : ''; + var text = $(this).text(); + var subtext = $(this).data('subtext') !== undefined ? ''+$(this).data('subtext')+'' : ''; + + //Append any subtext to the main text. + text+=subtext; + + if ($(this).parent().is('optgroup') && $(this).data('divider') != true) { + if ($(this).index() == 0) { + //Get the opt group label + var label = $(this).parent().attr('label'); + var labelSubtext = $(this).parent().data('subtext') !== undefined ? ''+$(this).parent().data('subtext')+'' : ''; + label += labelSubtext; + + if ($(this)[0].index != 0) { + _liA.push( + '
    '+ + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass ) + ); + } else { + _liA.push( + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass )); + } + } else { + _liA.push( _this.createA(text, "opt " + optionClass ) ); + } + } else if ($(this).data('divider') == true) { + _liA.push('
    '); + } else if ($(this).data('hidden') == true) { + _liA.push(''); + } else { + _liA.push( _this.createA(text, optionClass ) ); + } + }); + + if (_li.length > 0) { + for (var i = 0; i < _li.length; i++) { + var $option = this.$element.find('option').eq(i); + _liHtml += "
  • " + _liA[i] + "
  • "; + } + } + + //If we dont have a selected item, and we dont have a title, select the first element so something is set in the button + if(this.$element.find('option:selected').length==0 && !_this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return $(_liHtml); + }, + + createA:function(test, classes) { + return '' + + '' + test + '' + + ''; + + }, + + render:function() { + var _this = this; + + //Set width of select + if (this.options.width == 'auto') { + var ulWidth = this.$newElement.find('.dropdown-menu').css('width'); + this.$newElement.css('width',ulWidth); + } else if (this.options.width && this.options.width != 'auto') { + this.$newElement.css('width',this.options.width); + } + + //Update the LI to match the SELECT + this.$element.find('option').each(function(index) { + _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') ); + _this.setSelected(index, $(this).is(':selected') ); + }); + + + + var selectedItems = this.$element.find('option:selected').map(function(index,value) { + if($(this).attr('title')!=undefined) { + return $(this).attr('title'); + } else { + return $(this).text(); + } + }).toArray(); + + //Convert all the values into a comma delimited string + var title = selectedItems.join(", "); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) { + var max = _this.options.selectedTextFormat.split(">"); + if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) { + title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected'; + } + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if(!title) { + title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText; + } + + this.$element.next('.select').find('.filter-option').html( title ); + }, + + + + setSelected:function(index, selected) { + if(selected) { + this.$newElement.find('li').eq(index).addClass('selected'); + } else { + this.$newElement.find('li').eq(index).removeClass('selected'); + } + }, + + setDisabled:function(index, disabled) { + if(disabled) { + this.$newElement.find('li').eq(index).addClass('disabled'); + } else { + this.$newElement.find('li').eq(index).removeClass('disabled'); + } + }, + + checkDisabled: function() { + if (this.$element.is(':disabled')) { + this.button.addClass('disabled'); + this.button.click(function(e) { + e.preventDefault(); + }); + } + }, + + checkTabIndex: function() { + if (this.$element.is('[tabindex]')) { + var tabindex = this.$element.attr("tabindex"); + this.button.attr('tabindex', tabindex); + } + }, + + clickListener: function() { + var _this = this; + + $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); + + + + this.$newElement.on('click', 'li a', function(e){ + var clickedIndex = $(this).parent().index(), + $this = $(this).parent(), + $select = $this.parents('.select'); + + + //Dont close on multi choice menu + if(_this.multiple) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Dont run if we have been disabled + if ($select.prev('select').not(':disabled') && !$(this).parent().hasClass('disabled')){ + //Deselect all others if not multi select box + if (!_this.multiple) { + $select.prev('select').find('option').removeAttr('selected'); + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + //Else toggle the one we have chosen if we are multi selet. + else { + var selected = $select.prev('select').find('option').eq(clickedIndex).prop('selected'); + + if(selected) { + $select.prev('select').find('option').eq(clickedIndex).removeAttr('selected'); + } else { + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + } + + + $select.find('.filter-option').html($this.text()); + $select.find('button').focus(); + + // Trigger select 'change' + $select.prev('select').trigger('change'); + } + + }); + + this.$newElement.on('click', 'li.disabled a, li dt, li .divider', function(e) { + e.preventDefault(); + e.stopPropagation(); + $select = $(this).parent().parents('.select'); + $select.find('button').focus(); + }); + + this.$element.on('change', function(e) { + _this.render(); + }); + }, + + val:function(value) { + + if(value!=undefined) { + this.$element.val( value ); + + this.$element.trigger('change'); + return this.$element; + } else { + return this.$element.val(); + } + } + + }; + + $.fn.selectpicker = function(option, event) { + //get the args of the outer function.. + var args = arguments; + var value; + var chain = this.each(function () { + var $this = $(this), + data = $this.data('selectpicker'), + options = typeof option == 'object' && option; + + if (!data) { + $this.data('selectpicker', (data = new Selectpicker(this, options, event))); + } else { + for(var i in option) { + data[i]=option[i]; + } + } + + if (typeof option == 'string') { + //Copy the value of option, as once we shift the arguments + //it also shifts the value of option. + property = option; + if(data[property] instanceof Function) { + [].shift.apply(args); + value = data[property].apply(data, args); + } else { + value = data[property]; + } + } + }); + + if(value!=undefined) { + return value; + } else { + return chain; + } + }; + + $.fn.selectpicker.defaults = { + style: null, + size: 'auto', + title: null, + selectedTextFormat : 'values', + noneSelectedText : 'Nothing selected', + width: null, + menuStyle: null, + toggleSize: null + } + +}(window.jQuery); diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap.min.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/chartist.min.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/chartist.min.js new file mode 100644 index 0000000..b69e484 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/chartist.min.js @@ -0,0 +1,9 @@ +/* Chartist.js 0.9.4 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ + +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.Chartist=b()}):"object"==typeof exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.9.4"};return function(a,b,c){"use strict";c.noop=function(a){return a},c.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},c.extend=function(a){a=a||{};var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){for(var d in b)"object"!=typeof b[d]||null===b[d]||b[d]instanceof Array?a[d]=b[d]:a[d]=c.extend({},a[d],b[d])}),a},c.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},c.stripUnit=function(a){return"string"==typeof a&&(a=a.replace(/[^0-9\+-\.]/g,"")),+a},c.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},c.querySelector=function(a){return a instanceof Node?a:b.querySelector(a)},c.times=function(a){return Array.apply(null,new Array(a))},c.sum=function(a,b){return a+(b?b:0)},c.mapMultiply=function(a){return function(b){return b*a}},c.mapAdd=function(a){return function(b){return b+a}},c.serialMap=function(a,b){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return c.times(e).forEach(function(c,e){var f=a.map(function(a){return a[e]});d[e]=b.apply(null,f)}),d},c.roundWithPrecision=function(a,b){var d=Math.pow(10,b||c.precision);return Math.round(a*d)/d},c.precision=8,c.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},c.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,b,c.escapingMap[b])},a))},c.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,c.escapingMap[b],b)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(b){}return a},c.createSvg=function(a,b,d,e){var f;return b=b||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS("http://www.w3.org/2000/xmlns/",c.xmlNs.prefix)}).forEach(function(b){a.removeChild(b)}),f=new c.Svg("svg").attr({width:b,height:d}).addClass(e).attr({style:"width: "+b+"; height: "+d+";"}),a.appendChild(f._node),f},c.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;bf.high&&(f.high=c),h&&ck,m=e?c.rho(j.range):0;if(e&&c.projectLength(a,1,j)>=d)j.step=1;else if(e&&m=d)j.step=m;else for(;;){if(l&&c.projectLength(a,j.step,j)<=d)j.step*=2;else{if(l||!(c.projectLength(a,j.step/2,j)>=d))break;if(j.step/=2,e&&j.step%1!==0){j.step*=2;break}}if(i++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}for(g=j.min,h=j.max;g+j.step<=j.low;)g+=j.step;for(;h-j.step>=j.high;)h-=j.step;for(j.min=g,j.max=h,j.range=j.max-j.min,j.values=[],f=j.min;f<=j.max;f+=j.step)j.values.push(c.roundWithPrecision(f));return j},c.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},c.createChartRect=function(a,b,d){var e=!(!b.axisX&&!b.axisY),f=e?b.axisY.offset:0,g=e?b.axisX.offset:0,h=a.width()||c.stripUnit(b.width)||0,i=a.height()||c.stripUnit(b.height)||0,j=c.normalizePadding(b.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===b.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===b.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},c.createGrid=function(a,b,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",c.extend({type:"grid",axis:d,index:b,group:g,element:k},j))},c.createLabel=function(a,b,d,e,f,g,h,i,j,k,l){var m,n={};if(n[f.units.pos]=a+h[f.units.pos],n[f.counterUnits.pos]=h[f.counterUnits.pos],n[f.units.len]=b,n[f.counterUnits.len]=g-10,k){var o=''+e[d]+"";m=i.foreignObject(o,c.extend({style:"overflow: visible;"},n))}else m=i.elem("text",n,j.join(" ")).text(e[d]);l.emit("draw",c.extend({type:"label",axis:f,index:d,group:i,element:m,text:e[d]},n))},c.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},c.optionsProvider=function(b,d,e){function f(b){var f=h;if(h=c.extend({},j),d)for(i=0;i1){var i=[];return h.forEach(function(a){i.push(g(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(i)}if(a=h[0].pathCoordinates,d=h[0].valueData,a.length<=4)return c.Interpolation.none()(a,d);for(var j,k=(new c.Svg.Path).move(a[0],a[1],!1,d[0]),l=0,m=a.length;m-2*!j>l;l+=2){var n=[{x:+a[l-2],y:+a[l-1]},{x:+a[l],y:+a[l+1]},{x:+a[l+2],y:+a[l+3]},{x:+a[l+4],y:+a[l+5]}];j?l?m-4===l?n[3]={x:+a[0],y:+a[1]}:m-2===l&&(n[2]={x:+a[0],y:+a[1]},n[3]={x:+a[2],y:+a[3]}):n[0]={x:+a[m-2],y:+a[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+a[l],y:+a[l+1]}),k.curve(e*(-n[0].x+6*n[1].x+n[2].x)/6+f*n[2].x,e*(-n[0].y+6*n[1].y+n[2].y)/6+f*n[2].y,e*(n[1].x+6*n[2].x-n[3].x)/6+f*n[2].x,e*(n[1].y+6*n[2].y-n[3].y)/6+f*n[2].y,n[2].x,n[2].y,!1,d[(l+2)/2])}return k}},c.Interpolation.step=function(a){var b={postpone:!0};return a=c.extend({},b,a),function(b,d){for(var e=new c.Svg.Path,f=!0,g=2;g1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(h){var k=i.elem("path",{d:h.stringify()},a.classNames.area,!0).attr({values:b.normalized[g]},c.xmlNs.uri);this.eventEmitter.emit("draw",{type:"area",values:b.normalized[g],path:h.clone(),series:f,seriesIndex:g,axisX:d,axisY:e,chartRect:j,index:g,group:i,element:k})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:e.bounds,chartRect:j,axisX:d,axisY:e,svg:this.svg,options:a})}function e(a,b,d,e){c.Line["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Line=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a){var b,d={raw:this.data,normalized:a.distributeSeries?c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y").map(function(a){return[a]}):c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y")};this.svg=c.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var e=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars){var i=c.serialMap(d.normalized,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+b.x||0,y:a.y+b.y||0}},{x:0,y:0})});b=c.getHighLow([i],c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y")}else b=c.getHighLow(d.normalized,c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y");b.high=+a.high||(0===a.high?0:b.high),b.low=+a.low||(0===a.low?0:b.low);var j,k,l,m,n,o=c.createChartRect(this.svg,a,f.padding);k=a.distributeSeries&&a.stackBars?d.raw.labels.slice(0,1):d.raw.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})):a.axisX.type.call(c,c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})),l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y,d,o,{ticks:k}):a.axisY.type.call(c,c.Axis.units.y,d,o,a.axisY)):(l=m=void 0===a.axisX.type?new c.StepAxis(c.Axis.units.x,d,o,{ticks:k}):a.axisX.type.call(c,c.Axis.units.x,d,o,a.axisX),j=n=void 0===a.axisY.type?new c.AutoScaleAxis(c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})):a.axisY.type.call(c,c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),d.raw.series.forEach(function(b,e){var f,h,i=e-(d.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/d.normalized.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/d.normalized[e].length/2,h=g.elem("g"),h.attr({"series-name":b.name,meta:c.serialize(b.meta)},c.xmlNs.uri),h.addClass([a.classNames.series,b.className||a.classNames.series+"-"+c.alphaNumerate(e)].join(" ")),d.normalized[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,d.normalized[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,d.normalized[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,d.normalized[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,d.normalized[e])},l instanceof c.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],v[l.counterUnits.pos+"1"]=a.stackBars?t:p,v[l.counterUnits.pos+"2"]=a.stackBars?q[k]:r[l.counterUnits.pos],v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1),s=h.elem("line",v,a.classNames.bar).attr({value:[g.x,g.y].filter(function(a){return a}).join(","),meta:c.getMetaData(b,k)},c.xmlNs.uri), +this.eventEmitter.emit("draw",c.extend({type:"bar",value:g,index:k,meta:c.getMetaData(b,k),series:b,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function e(a,b,d,e){c.Bar["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,onlyInteger:!1,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,horizontalBars:!1,distributeSeries:!1,reverseData:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Bar=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function e(a){var b,e,f,h,i,j=[],k=a.startAngle,l=c.getDataArray(this.data,a.reverseData);this.svg=c.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=c.createChartRect(this.svg,a,g.padding),f=Math.min(e.width()/2,e.height()/2),i=a.total||l.reduce(function(a,b){return a+b},0),f-=a.donut?a.donutWidth/2:0,h="outside"===a.labelPosition||a.donut?f:"center"===a.labelPosition?0:f/2,h+=a.labelOffset;var m={x:e.x1+e.width()/2,y:e.y2+e.height()/2},n=1===this.data.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;a.showLabel&&(b=this.svg.elem("g",null,null,!0));for(var o=0;o180,0,r.x,r.y);a.donut||t.line(m.x,m.y);var u=j[o].elem("path",{d:t.stringify()},a.donut?a.classNames.sliceDonut:a.classNames.slicePie);if(u.attr({value:l[o],meta:c.serialize(p.meta)},c.xmlNs.uri),a.donut&&u.attr({style:"stroke-width: "+ +a.donutWidth+"px"}),this.eventEmitter.emit("draw",{type:"slice",value:l[o],totalDataSum:i,index:o,meta:p.meta,series:p,group:j[o],element:u,path:t.clone(),center:m,radius:f,startAngle:k,endAngle:q}),a.showLabel){var v=c.polarToCartesian(m.x,m.y,h,k+(q-k)/2),w=a.labelInterpolationFnc(this.data.labels?this.data.labels[o]:l[o],o);if(w||0===w){var x=b.elem("text",{dx:v.x,dy:v.y,"text-anchor":d(m,v,a.labelDirection)},a.classNames.label).text(""+w);this.eventEmitter.emit("draw",{type:"label",index:o,group:b,element:x,text:""+w,x:v.x,y:v.y})}}k=q}this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function f(a,b,d,e){c.Pie["super"].constructor.call(this,a,b,g,c.extend({},g,d),e)}var g={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:c.noop,labelDirection:"neutral",reverseData:!1};c.Pie=c.Base.extend({constructor:f,createChart:e,determineAnchorPosition:d})}(window,document,a),a}); +//# sourceMappingURL=chartist.min.js.map \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/demo.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/demo.js new file mode 100644 index 0000000..b4bb5ee --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/demo.js @@ -0,0 +1,152 @@ +type = ['','info','success','warning','danger']; + + +demo = { + initPickColor: function(){ + $('.pick-class-label').click(function(){ + var new_class = $(this).attr('new-class'); + var old_class = $('#display-buttons').attr('data-class'); + var display_div = $('#display-buttons'); + if(display_div.length) { + var display_buttons = display_div.find('.btn'); + display_buttons.removeClass(old_class); + display_buttons.addClass(new_class); + display_div.attr('data-class', new_class); + } + }); + }, + + initChartist: function(){ + + var dataSales = { + labels: ['9:00AM', '12:00AM', '3:00PM', '6:00PM', '9:00PM', '12:00PM', '3:00AM', '6:00AM'], + series: [ + [287, 385, 490, 492, 554, 586, 698, 695, 752, 788, 846, 944], + [67, 152, 143, 240, 287, 335, 435, 437, 539, 542, 544, 647], + [23, 113, 67, 108, 190, 239, 307, 308, 439, 410, 410, 509] + ] + }; + + var optionsSales = { + lineSmooth: false, + low: 0, + high: 800, + showArea: true, + height: "245px", + axisX: { + showGrid: false, + }, + lineSmooth: Chartist.Interpolation.simple({ + divisor: 3 + }), + showLine: false, + showPoint: false, + }; + + var responsiveSales = [ + ['screen and (max-width: 640px)', { + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Line('#chartHours', dataSales, optionsSales, responsiveSales); + + + var data = { + labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + series: [ + [542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895], + [412, 243, 280, 580, 453, 353, 300, 364, 368, 410, 636, 695] + ] + }; + + var options = { + seriesBarDistance: 10, + axisX: { + showGrid: false + }, + height: "245px" + }; + + var responsiveOptions = [ + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Bar('#chartActivity', data, options, responsiveOptions); + + var dataPreferences = { + series: [ + [25, 30, 20, 25] + ] + }; + + var optionsPreferences = { + donut: true, + donutWidth: 40, + startAngle: 0, + total: 100, + showLabel: false, + axisX: { + showGrid: false + } + }; + + Chartist.Pie('#chartPreferences', dataPreferences, optionsPreferences); + + Chartist.Pie('#chartPreferences', { + labels: ['62%','32%','6%'], + series: [62, 32, 6] + }); + }, + + initGoogleMaps: function(){ + var myLatlng = new google.maps.LatLng(40.748817, -73.985428); + var mapOptions = { + zoom: 13, + center: myLatlng, + scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page + styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}] + + } + var map = new google.maps.Map(document.getElementById("map"), mapOptions); + + var marker = new google.maps.Marker({ + position: myLatlng, + title:"Hello World!" + }); + + // To add the marker to the map, call setMap(); + marker.setMap(map); + }, + + showNotification: function(from, align){ + color = Math.floor((Math.random() * 4) + 1); + + $.notify({ + icon: "pe-7s-gift", + message: "Welcome to Light Bootstrap Dashboard - a beautiful freebie for every web developer." + + },{ + type: type[color], + timer: 4000, + placement: { + from: from, + align: align + } + }); + } + + +} + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/jquery-1.10.2.js b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/jquery-1.10.2.js new file mode 100644 index 0000000..d6f6ac8 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/html/assets/js/jquery-1.10.2.js @@ -0,0 +1,9789 @@ +/*! + * jQuery JavaScript Library v1.10.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:48Z + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<10 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.10.2", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( jQuery.support.ownLast ) { + for ( key in obj ) { + return core_hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.10.2 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
    "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + + var all, a, input, select, fragment, opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
    a"; + + // Finish early in limited (non-browser) environments + all = div.getElementsByTagName("*") || []; + a = div.getElementsByTagName("a")[ 0 ]; + if ( !a || !a.style || !all.length ) { + return support; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName("tbody").length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName("link").length; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + support.opacity = /^0.5/.test( a.style.opacity ); + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!a.style.cssFloat; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; + + // Will be defined later + support.inlineBlockNeedsLayout = false; + support.shrinkWrapBlocks = false; + support.pixelPosition = false; + support.deleteExpando = true; + support.noCloneEvent = true; + support.reliableMarginRight = true; + support.boxSizingReliable = true; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: IE<9 + // Iteration over object's inherited properties before its own. + for ( i in jQuery( support ) ) { + break; + } + support.ownLast = i !== "0"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior. + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
    "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})({}); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "applet": true, + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + data = null, + i = 0, + elem = this[0]; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( name.indexOf("data-") === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // Use proper attribute retrieval(#6932, #12072) + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + jQuery.expr.attrHandle[ name ] = fn; + return ret; + } : + function( elem, name, isXML ) { + return isXML ? + undefined : + elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = + // Some attributes are constructed with empty-string values when not defined + function( elem, name, isXML ) { + var ret; + return isXML ? + undefined : + (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + }; + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ret.specified ? + ret.value : + undefined; + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = ret.push( cur ); + break; + } + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
    ", "
    " ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + col: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
    ", "
    " ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
    " && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(" + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donutchartssimple.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/README.md b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/dashboard.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/graphs.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/metricdescriptions.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/notifications.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/table.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/template.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartmethod.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartpackage.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartx.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/defaultclassmetrics.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/overview_metric_data.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..a300ba5 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-juss", "Number of Highly Problematic Classes":0, "Number of Entities":10, "Number of Problematic Classes":1, "Class Lines of Code":820, "Number of External Packages":14, "Number of Packages":3, "Number of External Entities":209} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/packagedependency.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..6cb3f91 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/packagedependency.js @@ -0,0 +1,11 @@ +var matrix = [[0,0,0],[0,0,0],[0,1,0]] +var packages = [{ +"name": " org.ugp.serialx.juss.protocols", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.juss", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.juss.converters", "color": " #9ecae1" +} +]; diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/summary_data.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..af74881 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 336,count:1}, +{label:"fair quality attributes", color: "#007F24", value: 484,count:9}]; diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/sunburst_data.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..03e8141 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,139 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-juss", "value":820, +"prmetrics":{"5":1,"6":1,"7":1,"8":1,"9":2,"10":1,"11":3}, +"prmetricvalues":{"5":0,"6":10,"7":1,"8":820,"9":14,"10":3,"11":209}, +"children": [ { +"name": "org.ugp.serialx.juss.protocols", "value":113, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":2,"13":1,"14":3,"3":1,"1":1,"0":1,"17":0.25,"6":4,"18":0.25,"8":113,"19":1.0,"2":1,"15":0,"16":44}, +"children":[ +{ +"name": "UniversalObjectInstantiationProtocol","key": "m","value":40, +"metrics":{"20":1,"21":1,"22":1,"23":3,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.4,"24":38,"25":1,"26":2,"0":2,"27":5,"28":14,"29":0.9,"30":0.0,"31":0,"32":0.55,"39":0,"33":0,"34":9,"40":1,"35":0,"36":3,"16":14,"37":1,"4":1,"8":40,"2":1,"3":1,"1":2} +}, +{ +"name": "SelfSerializableProtocol","key": "q","value":9, +"metrics":{"20":1,"21":1,"22":1,"23":5,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":1,"38":1,"22":0,"23":2.0,"24":8,"25":0,"26":3,"0":2,"27":3,"28":4,"29":0.0,"30":0.0,"31":0,"32":0.444,"39":1,"33":0,"34":1,"40":0,"35":0,"36":0,"16":3,"37":2,"4":1,"8":9,"2":1,"3":1,"1":2} +}, +{ +"name": "SelfSerializable","key": "t","value":2, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":1,"25":0,"26":1,"0":1,"27":1,"28":1,"29":0.0,"30":0.0,"31":0,"32":0.0,"33":0,"34":0,"35":0,"36":0,"16":1,"37":0,"4":1,"8":2,"2":1,"3":1,"1":1} +}, +{ +"name": "AutoProtocol","key": "s","value":62, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":2,"0":2,"27":1,"28":1,"29":4,"30":4,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"22":4,"23":0.0,"24":52,"25":0,"26":2,"0":2,"27":11,"28":26,"29":0.836,"30":0.878,"31":3,"32":0.662,"33":0,"34":19,"35":0,"36":3,"16":26,"37":0,"4":2,"8":62,"2":1,"3":2,"1":2} +} +] +},{ +"name": "org.ugp.serialx.juss", "value":336, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":2,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":1,"3":1,"1":1,"0":1,"17":0.5,"6":1,"18":0.0,"8":336,"19":0.5,"2":1,"15":1,"16":175}, +"children":[ +{ +"name": "JussSerializer","key": "k","value":336, +"metrics":{"20":2,"21":1,"22":1,"23":4,"24":3,"25":1,"26":3,"0":5,"27":2,"28":2,"29":5,"30":5,"31":1,"32":4,"33":1,"34":2,"35":1,"36":2,"16":5,"37":1,"4":3,"8":3,"2":2,"3":4,"1":5}, +"metricvalues":{"20":9,"21":1,"38":1,"22":2,"23":0.444,"24":322,"25":0,"26":4,"0":5,"27":27,"28":86,"29":0.991,"30":1.071,"31":2,"32":0.852,"39":0,"33":0,"34":68,"40":1,"35":2,"36":9,"16":175,"37":3,"4":3,"8":336,"2":2,"3":4,"1":5} +} +] +},{ +"name": "org.ugp.serialx.juss.converters", "value":371, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":5,"13":0,"14":5,"3":1,"1":2,"0":2,"17":0.0,"6":5,"18":0.0,"8":371,"19":1.0,"2":1,"15":0,"16":204}, +"children":[ +{ +"name": "VariableConverter","key": "u","value":105, +"metrics":{"20":1,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":5,"21":0,"22":1,"23":0.25,"24":101,"25":0,"26":2,"0":3,"27":8,"28":35,"29":0.978,"30":1.0,"31":1,"32":0.662,"33":0,"34":28,"35":2,"36":5,"16":61,"37":1,"4":2,"8":105,"2":1,"3":2,"1":3} +}, +{ +"name": "OperationGroups","key": "r","value":82, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"22":1,"23":0.0,"24":80,"25":0,"26":1,"0":2,"27":1,"28":20,"29":1.0,"30":0.0,"31":0,"32":0.464,"33":0,"34":19,"35":3,"36":3,"16":49,"37":0,"4":2,"8":82,"2":1,"3":1,"1":2} +}, +{ +"name": "ObjectConverter","key": "v","value":76, +"metrics":{"20":2,"21":1,"22":1,"23":3,"24":2,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":2,"37":1,"4":2,"8":2,"2":2,"3":1,"1":2}, +"metricvalues":{"20":10,"21":0,"38":1,"22":0,"23":0.4,"24":75,"25":0,"26":2,"0":2,"27":5,"28":34,"29":0.0,"30":0.0,"31":0,"32":0.433,"39":1,"33":1,"34":31,"40":0,"35":0,"36":9,"16":36,"37":1,"4":2,"8":76,"2":2,"3":1,"1":2} +}, +{ +"name": "ArrayConverter","key": "o","value":77, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":1,"1":2}, +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":76,"25":0,"26":1,"0":2,"27":4,"28":23,"29":0.0,"30":0.0,"31":0,"32":0.417,"33":0,"34":20,"35":0,"36":3,"16":44,"37":0,"4":2,"8":77,"2":1,"3":1,"1":2} +}, +{ +"name": "ImportConverter","key": "p","value":31, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":2,"16":1,"37":1,"4":1,"8":1,"2":2,"3":1,"1":1}, +"metricvalues":{"20":6,"21":0,"22":0,"23":0.0,"24":30,"25":0,"26":1,"0":2,"27":3,"28":17,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":0,"34":15,"35":0,"36":6,"16":14,"37":0,"4":1,"8":31,"2":2,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/table_data.js b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..38284ea --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#1)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1JussSerializer ▄ ▄ ▄ ▄336175862724';var EQ_Table5_Title = 'List of all classes (#10)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1JussSerializer ▄ ▄ ▄ ▄336very-highlow-mediumhighmedium-high2ObjectConverter ▄ ▄ ▄ ▄76low-mediumlow-mediumlowlow-medium3ImportConverter ▄ ▄ ▄ ▄31lowlow-mediumlowlow4VariableConverter ▄ ▄ ▄ ▄105medium-highlowlow-mediumlow-medium5OperationGroups ▄ ▄ ▄ ▄82low-mediumlowlowlow-medium6ArrayConverter ▄ ▄ ▄ ▄77low-mediumlowlowlow-medium7AutoProtocol ▄ ▄ ▄ ▄62low-mediumlowlow-mediumlow-medium8UniversalObjectIn... ▄ ▄ ▄ ▄40low-mediumlowlowlow9SelfSerializableP... ▄ ▄ ▄ ▄9low-mediumlowlowlow10SelfSerializable ▄ ▄ ▄ ▄2lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/report.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/reportforprint.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/sunburst.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/treemap.html b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/main_report/index.html b/SerialX-juss/codemr/serialx-juss/html/main_report/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/main_report/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/html/workingsets.js b/SerialX-juss/codemr/serialx-juss/html/workingsets.js new file mode 100644 index 0000000..a51c485 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/html/workingsets.js @@ -0,0 +1,3 @@ +var EQ_workingSetList = [ +{name: 'serialx-juss', path:'serialx-juss'} +]; diff --git a/SerialX-juss/codemr/serialx-juss/serialx-juss.mdl b/SerialX-juss/codemr/serialx-juss/serialx-juss.mdl new file mode 100644 index 0000000000000000000000000000000000000000..7df0f75ab59ee8b3f20e2ea6872e15cb7984233c GIT binary patch literal 27483 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 literal 0 HcmV?d00001 diff --git a/SerialX-juss/codemr/serialx-juss/serialx-juss.qa b/SerialX-juss/codemr/serialx-juss/serialx-juss.qa new file mode 100644 index 0000000..aaae8d4 --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/serialx-juss.qa @@ -0,0 +1 @@ +{"metrics":{"Number of Highly Problematic Classes":0,"Number of Entities":10,"Number of Problematic Classes":1,"Class Lines of Code":820,"Number of External Packages":14,"Number of Packages":3,"Number of External Entities":209},"distributions":{"Coupling":{"distribution":[0,7,3,0,0,0],"locDistribution":[0,377,443,0,0,0]},"Lack of Cohesion":{"distribution":[0,7,2,0,1,0],"locDistribution":[0,317,167,0,336,0]},"Complexity":{"distribution":[0,2,6,1,0,1],"locDistribution":[0,33,346,105,0,336]}}} \ No newline at end of file diff --git a/SerialX-juss/codemr/serialx-juss/serialx-juss.ws b/SerialX-juss/codemr/serialx-juss/serialx-juss.ws new file mode 100644 index 0000000..b79536c --- /dev/null +++ b/SerialX-juss/codemr/serialx-juss/serialx-juss.ws @@ -0,0 +1 @@ +{"serialx-juss":{"name":"serialx-juss","packages":{"org.ugp.serialx.juss.protocols":{"packageName":"org.ugp.serialx.juss.protocols","isAll":false,"classes":["Lorg/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol;","Lorg/ugp/serialx/juss/protocols/SelfSerializableProtocol;","Lorg/ugp/serialx/juss/protocols/SelfSerializable;","Lorg/ugp/serialx/juss/protocols/AutoProtocol;"]},"org.ugp.serialx.juss":{"packageName":"org.ugp.serialx.juss","isAll":false,"classes":["Lorg/ugp/serialx/juss/JussSerializer;"]},"org.ugp.serialx.juss.converters":{"packageName":"org.ugp.serialx.juss.converters","isAll":false,"classes":["Lorg/ugp/serialx/juss/converters/VariableConverter;","Lorg/ugp/serialx/juss/converters/OperationGroups;","Lorg/ugp/serialx/juss/converters/ObjectConverter;","Lorg/ugp/serialx/juss/converters/ArrayConverter;","Lorg/ugp/serialx/juss/converters/ImportConverter;"]}}}} \ No newline at end of file From 2e502e9435fab2e721b903f2801b669a83bd7ec5 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 28 Sep 2026 19:20:26 +0200 Subject: [PATCH 72/75] codemr graph for core module --- .../serialx-core/graphs/all_bymodularity.cmr | 2 +- .../serialx-core/graphs/all_bypackage.cmr | 2 +- .../graphs/all_byprojectmodule.cmr | 2 +- .../codemr/serialx-core/graphs/all_nm.cmr | 2 +- .../graphs/all_nm_inheritance 1.3.9.cmr | 1 + .../graphs/all_nm_inheritance.cmr | 2 +- .../html/graph_htmls/all_bymodularity.html | 2 +- .../html/graph_htmls/all_bymodularity.png | Bin 25490 -> 27506 bytes .../html/graph_htmls/all_bypackage.html | 2 +- .../html/graph_htmls/all_bypackage.png | Bin 32694 -> 2836 bytes .../html/graph_htmls/all_byprojectmodule.html | 2 +- .../html/graph_htmls/all_byprojectmodule.png | Bin 15339 -> 21825 bytes .../serialx-core/html/graph_htmls/all_nm.html | 2 +- .../serialx-core/html/graph_htmls/all_nm.png | Bin 25932 -> 24091 bytes .../graph_htmls/all_nm_inheritance 1.3.9.html | 1 + .../graph_htmls/all_nm_inheritance 1.3.9.png | Bin 0 -> 9958 bytes .../html/graph_htmls/all_nm_inheritance.html | 2 +- .../html/graph_htmls/all_nm_inheritance.png | Bin 10401 -> 9299 bytes .../html/graph_htmls/graphlist.js | 2 +- 19 files changed, 13 insertions(+), 11 deletions(-) create mode 100644 SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.html create mode 100644 SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.png diff --git a/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr b/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr index c613da6..e6bba07 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_bymodularity.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":388.0,"y":128.0},"B":{"x":1015.0,"y":356.0},"C":{"x":213.0,"y":114.0},"D":{"x":411.0,"y":1086.0},"E":{"x":194.0,"y":297.0},"G":{"x":236.0,"y":434.0},"H":{"x":809.0,"y":633.0},"I":{"x":1144.0,"y":411.0},"J":{"x":296.0,"y":988.0},"K":{"x":338.0,"y":140.0},"L":{"x":210.0,"y":442.0},"M":{"x":335.0,"y":1205.0},"N":{"x":253.0,"y":143.0},"O":{"x":50.0,"y":327.0},"P":{"x":358.0,"y":489.0},"Q":{"x":276.0,"y":401.0},"k":{"x":257.0,"y":894.0},"m":{"x":386.0,"y":306.0},"o":{"x":930.0,"y":627.0},"r":{"x":284.0,"y":192.0},"s":{"x":496.0,"y":968.0},"t":{"x":293.0,"y":50.0},"w":{"x":555.0,"y":1169.0},"x":{"x":305.0,"y":366.0},"y":{"x":964.0,"y":488.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]}],"clusterMap":{"A":3,"B":4,"C":3,"D":2,"E":1,"G":1,"H":4,"I":4,"J":2,"K":3,"L":1,"M":2,"N":3,"O":1,"P":1,"Q":1,"k":2,"m":1,"o":4,"r":3,"s":2,"t":3,"w":2,"x":1,"y":4}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":352.0,"y":107.0},"B":{"x":953.0,"y":318.0},"C":{"x":175.0,"y":128.0},"D":{"x":423.0,"y":1074.0},"E":{"x":183.0,"y":341.0},"G":{"x":242.0,"y":473.0},"H":{"x":805.0,"y":613.0},"I":{"x":1078.0,"y":257.0},"J":{"x":312.0,"y":988.0},"K":{"x":303.0,"y":130.0},"L":{"x":216.0,"y":483.0},"M":{"x":615.0,"y":1052.0},"N":{"x":220.0,"y":149.0},"O":{"x":50.0,"y":404.0},"P":{"x":370.0,"y":510.0},"Q":{"x":277.0,"y":434.0},"k":{"x":288.0,"y":888.0},"m":{"x":374.0,"y":325.0},"o":{"x":894.0,"y":530.0},"r":{"x":260.0,"y":190.0},"s":{"x":495.0,"y":947.0},"t":{"x":242.0,"y":50.0},"w":{"x":488.0,"y":1210.0},"x":{"x":301.0,"y":396.0},"y":{"x":1012.0,"y":447.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]}],"clusterMap":{"A":3,"B":4,"C":3,"D":2,"E":1,"G":1,"H":4,"I":4,"J":2,"K":3,"L":1,"M":2,"N":3,"O":1,"P":1,"Q":1,"k":2,"m":1,"o":4,"r":3,"s":2,"t":3,"w":2,"x":1,"y":4}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr b/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr index 4771ba4..c3bc616 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_bypackage.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":527.0,"y":50.0},"B":{"x":858.0,"y":227.0},"C":{"x":421.0,"y":184.0},"D":{"x":801.0,"y":326.0},"E":{"x":716.0,"y":152.0},"G":{"x":765.0,"y":260.0},"H":{"x":988.0,"y":782.0},"I":{"x":825.0,"y":1060.0},"J":{"x":50.0,"y":730.0},"K":{"x":506.0,"y":113.0},"L":{"x":708.0,"y":293.0},"M":{"x":238.0,"y":879.0},"N":{"x":340.0,"y":157.0},"O":{"x":867.0,"y":1189.0},"P":{"x":831.0,"y":366.0},"Q":{"x":740.0,"y":283.0},"k":{"x":149.0,"y":691.0},"m":{"x":860.0,"y":191.0},"o":{"x":873.0,"y":748.0},"r":{"x":521.0,"y":172.0},"s":{"x":250.0,"y":657.0},"t":{"x":410.0,"y":83.0},"w":{"x":755.0,"y":1270.0},"x":{"x":670.0,"y":310.0},"y":{"x":928.0,"y":182.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]}],"clusterMap":{"A":2,"B":1,"C":2,"D":1,"E":1,"G":1,"H":5,"I":4,"J":3,"K":2,"L":1,"M":3,"N":2,"O":4,"P":1,"Q":1,"k":3,"m":1,"o":5,"r":2,"s":3,"t":2,"w":4,"x":1,"y":1}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":173.0,"y":114.0},"B":{"x":511.0,"y":183.0},"C":{"x":50.0,"y":231.0},"D":{"x":402.0,"y":234.0},"E":{"x":429.0,"y":55.0},"G":{"x":396.0,"y":182.0},"H":{"x":808.0,"y":735.0},"I":{"x":278.0,"y":1131.0},"J":{"x":734.0,"y":673.0},"K":{"x":115.0,"y":50.0},"L":{"x":364.0,"y":187.0},"M":{"x":595.0,"y":869.0},"N":{"x":111.0,"y":209.0},"O":{"x":187.0,"y":1232.0},"P":{"x":467.0,"y":302.0},"Q":{"x":424.0,"y":188.0},"k":{"x":630.0,"y":653.0},"m":{"x":558.0,"y":167.0},"o":{"x":807.0,"y":856.0},"r":{"x":152.0,"y":232.0},"s":{"x":522.0,"y":658.0},"t":{"x":51.0,"y":129.0},"w":{"x":60.0,"y":1165.0},"x":{"x":509.0,"y":151.0},"y":{"x":617.0,"y":155.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]}],"clusterMap":{"A":2,"B":1,"C":2,"D":1,"E":1,"G":1,"H":5,"I":4,"J":3,"K":2,"L":1,"M":3,"N":2,"O":4,"P":1,"Q":1,"k":3,"m":1,"o":5,"r":2,"s":3,"t":2,"w":4,"x":1,"y":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr b/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr index 551c10e..3be3888 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_byprojectmodule.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":353.0,"y":175.0},"B":{"x":362.0,"y":237.0},"C":{"x":411.0,"y":104.0},"D":{"x":304.0,"y":300.0},"E":{"x":324.0,"y":115.0},"G":{"x":293.0,"y":245.0},"H":{"x":695.0,"y":326.0},"I":{"x":236.0,"y":268.0},"J":{"x":153.0,"y":275.0},"K":{"x":248.0,"y":163.0},"L":{"x":325.0,"y":255.0},"M":{"x":472.0,"y":260.0},"N":{"x":285.0,"y":151.0},"O":{"x":172.0,"y":125.0},"P":{"x":359.0,"y":379.0},"Q":{"x":420.0,"y":237.0},"k":{"x":50.0,"y":275.0},"m":{"x":279.0,"y":276.0},"o":{"x":620.0,"y":229.0},"r":{"x":326.0,"y":171.0},"s":{"x":398.0,"y":157.0},"t":{"x":297.0,"y":50.0},"w":{"x":399.0,"y":403.0},"x":{"x":402.0,"y":266.0},"y":{"x":467.0,"y":202.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"H":1,"I":1,"J":1,"K":1,"L":1,"M":1,"N":1,"O":1,"P":1,"Q":1,"k":1,"m":1,"o":1,"r":1,"s":1,"t":1,"w":1,"x":1,"y":1}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":242.0,"y":161.0},"B":{"x":186.0,"y":217.0},"C":{"x":357.0,"y":95.0},"D":{"x":247.0,"y":289.0},"E":{"x":267.0,"y":100.0},"G":{"x":222.0,"y":224.0},"H":{"x":636.0,"y":329.0},"I":{"x":216.0,"y":317.0},"J":{"x":118.0,"y":340.0},"K":{"x":203.0,"y":155.0},"L":{"x":295.0,"y":230.0},"M":{"x":100.0,"y":163.0},"N":{"x":173.0,"y":118.0},"O":{"x":156.0,"y":188.0},"P":{"x":282.0,"y":357.0},"Q":{"x":364.0,"y":217.0},"k":{"x":50.0,"y":417.0},"m":{"x":253.0,"y":245.0},"o":{"x":566.0,"y":230.0},"r":{"x":229.0,"y":177.0},"s":{"x":347.0,"y":164.0},"t":{"x":245.0,"y":50.0},"w":{"x":381.0,"y":366.0},"x":{"x":339.0,"y":238.0},"y":{"x":420.0,"y":195.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"H":1,"I":1,"J":1,"K":1,"L":1,"M":1,"N":1,"O":1,"P":1,"Q":1,"k":1,"m":1,"o":1,"r":1,"s":1,"t":1,"w":1,"x":1,"y":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr index e1fcf86..3d0e409 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":190.0,"y":356.0},"B":{"x":615.0,"y":311.0},"C":{"x":524.0,"y":240.0},"D":{"x":249.0,"y":329.0},"E":{"x":460.0,"y":97.0},"G":{"x":337.0,"y":300.0},"H":{"x":746.0,"y":696.0},"I":{"x":649.0,"y":576.0},"J":{"x":50.0,"y":259.0},"K":{"x":566.0,"y":601.0},"L":{"x":605.0,"y":287.0},"M":{"x":200.0,"y":595.0},"N":{"x":201.0,"y":463.0},"O":{"x":274.0,"y":228.0},"P":{"x":467.0,"y":497.0},"Q":{"x":627.0,"y":289.0},"k":{"x":120.0,"y":50.0},"m":{"x":289.0,"y":283.0},"o":{"x":869.0,"y":489.0},"r":{"x":429.0,"y":702.0},"s":{"x":429.0,"y":186.0},"t":{"x":420.0,"y":435.0},"w":{"x":436.0,"y":486.0},"x":{"x":644.0,"y":312.0},"y":{"x":708.0,"y":283.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]}],"clusterMap":{}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":25},{"@type":"int","id":"#edges","v":63},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":358.0,"y":350.0},"B":{"x":455.0,"y":384.0},"C":{"x":51.0,"y":90.0},"D":{"x":340.0,"y":495.0},"E":{"x":273.0,"y":213.0},"G":{"x":143.0,"y":418.0},"H":{"x":694.0,"y":718.0},"I":{"x":243.0,"y":534.0},"J":{"x":138.0,"y":572.0},"K":{"x":270.0,"y":347.0},"L":{"x":436.0,"y":400.0},"M":{"x":126.0,"y":312.0},"N":{"x":476.0,"y":50.0},"O":{"x":50.0,"y":314.0},"P":{"x":294.0,"y":604.0},"Q":{"x":455.0,"y":406.0},"k":{"x":213.0,"y":366.0},"m":{"x":403.0,"y":407.0},"o":{"x":755.0,"y":485.0},"r":{"x":397.0,"y":336.0},"s":{"x":485.0,"y":311.0},"t":{"x":269.0,"y":128.0},"w":{"x":512.0,"y":645.0},"x":{"x":482.0,"y":399.0},"y":{"x":528.0,"y":354.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"x"},{"type":"D"},{"type":"K"},{"type":"J"},{"type":"L"},{"type":"I"},{"type":"o"},{"type":"r"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"H"},{"type":"Q"},{"type":"k"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"w"},{"type":"t"},{"type":"m"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"J","d":"w","k":55,"w":7}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"y","d":"o","k":55,"w":2}]},{"L":[{"s":"Q","d":"E","k":51,"w":3}]},{"L":[{"s":"J","d":"k","k":3,"w":1},{"s":"J","d":"k","k":55,"w":3}]},{"L":[{"s":"w","d":"E","k":55,"w":4},{"s":"w","d":"E","k":53,"w":1},{"s":"w","d":"E","k":51,"w":1},{"s":"w","d":"E","k":7,"w":1}]},{"L":[{"s":"r","d":"M","k":55,"w":2}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"G","d":"E","k":51,"w":3}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":2}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"I","k":55,"w":2}]},{"L":[{"s":"x","d":"E","k":51,"w":3}]},{"L":[{"s":"x","d":"w","k":55,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1},{"s":"D","d":"E","k":51,"w":2}]},{"L":[{"s":"r","d":"I","k":55,"w":1}]},{"L":[{"s":"D","d":"M","k":55,"w":4},{"s":"D","d":"M","k":51,"w":1}]},{"L":[{"s":"t","d":"I","k":55,"w":3}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"w","k":55,"w":2}]},{"L":[{"s":"H","d":"o","k":6,"w":1},{"s":"H","d":"o","k":51,"w":4}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"O","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":55,"w":4},{"s":"y","d":"t","k":51,"w":2}]},{"L":[{"s":"J","d":"E","k":6,"w":2},{"s":"J","d":"E","k":55,"w":5},{"s":"J","d":"E","k":53,"w":1},{"s":"J","d":"E","k":51,"w":4},{"s":"J","d":"E","k":7,"w":1}]},{"L":[{"s":"D","d":"J","k":55,"w":1}]},{"L":[{"s":"s","d":"I","k":55,"w":1}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"y","d":"w","k":55,"w":4}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"w","k":55,"w":3}]},{"L":[{"s":"L","d":"E","k":51,"w":3}]},{"L":[{"s":"D","d":"s","k":53,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1},{"s":"t","d":"O","k":55,"w":2}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1},{"s":"s","d":"M","k":55,"w":47},{"s":"s","d":"M","k":51,"w":6},{"s":"s","d":"M","k":58,"w":1},{"s":"s","d":"M","k":7,"w":1}]},{"L":[{"s":"J","d":"M","k":55,"w":7},{"s":"J","d":"M","k":51,"w":6},{"s":"J","d":"M","k":58,"w":4}]},{"L":[{"s":"o","d":"H","k":51,"w":2},{"s":"o","d":"H","k":7,"w":1}]},{"L":[{"s":"m","d":"E","k":51,"w":3}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"J","d":"m","k":55,"w":1}]},{"L":[{"s":"w","d":"s","k":53,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1},{"s":"P","d":"E","k":51,"w":3}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1},{"s":"E","d":"P","k":6,"w":1},{"s":"E","d":"P","k":51,"w":3}]},{"L":[{"s":"J","d":"t","k":6,"w":1},{"s":"J","d":"t","k":55,"w":2},{"s":"J","d":"t","k":51,"w":5}]},{"L":[{"s":"m","d":"w","k":55,"w":4}]},{"L":[{"s":"M","d":"w","k":55,"w":4}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"J","k":55,"w":3},{"s":"w","d":"J","k":51,"w":1}]},{"L":[{"s":"M","d":"t","k":55,"w":2},{"s":"M","d":"t","k":51,"w":2}]},{"L":[{"s":"y","d":"s","k":7,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"w","k":55,"w":4}]},{"L":[{"s":"L","d":"w","k":55,"w":2}]},{"L":[{"s":"A","d":"M","k":55,"w":4},{"s":"A","d":"M","k":51,"w":2},{"s":"A","d":"M","k":7,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":1}]},{"L":[{"s":"y","d":"E","k":55,"w":4},{"s":"y","d":"E","k":51,"w":6}]},{"L":[{"s":"B","d":"E","k":51,"w":3}]},{"L":[{"s":"y","d":"I","k":55,"w":5}]},{"L":[{"s":"J","d":"s","k":2,"w":1},{"s":"J","d":"s","k":55,"w":12},{"s":"J","d":"s","k":53,"w":1},{"s":"J","d":"s","k":51,"w":4},{"s":"J","d":"s","k":58,"w":3},{"s":"J","d":"s","k":7,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr new file mode 100644 index 0000000..63b70f1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":20},{"@type":"int","id":"#edges","v":19},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":398.0,"y":520.0},"B":{"x":547.0,"y":50.0},"C":{"x":398.0,"y":441.0},"D":{"x":392.0,"y":278.0},"E":{"x":249.0,"y":247.0},"G":{"x":547.0,"y":222.0},"J":{"x":354.0,"y":52.0},"K":{"x":397.0,"y":359.0},"L":{"x":545.0,"y":183.0},"M":{"x":60.0,"y":54.0},"m":{"x":549.0,"y":269.0},"N":{"x":397.0,"y":399.0},"O":{"x":50.0,"y":320.0},"P":{"x":394.0,"y":214.0},"Q":{"x":548.0,"y":88.0},"r":{"x":399.0,"y":480.0},"s":{"x":217.0,"y":52.0},"t":{"x":249.0,"y":413.0},"x":{"x":552.0,"y":322.0},"y":{"x":545.0,"y":131.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"J":1,"K":1,"L":1,"M":1,"m":1,"N":1,"O":1,"P":1,"Q":1,"r":1,"s":1,"t":1,"x":1,"y":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr index b081b12..ff0d125 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":21},{"@type":"int","id":"#edges","v":20},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":434.0,"y":192.0},"B":{"x":596.0,"y":430.0},"C":{"x":434.0,"y":276.0},"D":{"x":434.0,"y":524.0},"E":{"x":252.0,"y":503.0},"G":{"x":596.0,"y":472.0},"J":{"x":434.0,"y":50.0},"k":{"x":596.0,"y":50.0},"K":{"x":434.0,"y":360.0},"L":{"x":596.0,"y":638.0},"M":{"x":50.0,"y":50.0},"m":{"x":596.0,"y":378.0},"N":{"x":434.0,"y":318.0},"O":{"x":50.0,"y":390.0},"P":{"x":434.0,"y":482.0},"Q":{"x":596.0,"y":326.0},"r":{"x":434.0,"y":234.0},"s":{"x":252.0,"y":50.0},"t":{"x":252.0,"y":276.0},"x":{"x":596.0,"y":524.0},"y":{"x":596.0,"y":586.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"k"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]}],"clusterMap":{}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":21},{"@type":"int","id":"#edges","v":20},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":434.0,"y":613.0},"B":{"x":596.0,"y":172.0},"C":{"x":434.0,"y":487.0},"D":{"x":434.0,"y":365.0},"E":{"x":252.0,"y":344.0},"G":{"x":596.0,"y":338.0},"J":{"x":434.0,"y":50.0},"k":{"x":596.0,"y":50.0},"K":{"x":434.0,"y":655.0},"L":{"x":596.0,"y":422.0},"M":{"x":50.0,"y":50.0},"m":{"x":596.0,"y":286.0},"N":{"x":434.0,"y":529.0},"O":{"x":50.0,"y":458.0},"P":{"x":434.0,"y":323.0},"Q":{"x":596.0,"y":380.0},"r":{"x":434.0,"y":571.0},"s":{"x":252.0,"y":50.0},"t":{"x":252.0,"y":571.0},"x":{"x":596.0,"y":474.0},"y":{"x":596.0,"y":224.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"k"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"J","d":"k","k":3,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html index 7f3bed7..9585e30 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png index e8e3e538261db4f1c477100f592221bd55eecd85..9054b7d5c896edb0ba9a9fdc9494cb2e77b2ccdd 100644 GIT binary patch literal 27506 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î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 V`Vr?0_^pi>%JS-R4Km=c{|EM?z={9> diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html index 7c5cd99..d4192c0 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png index 37e491fd3f78adc8efb8cdb2054ff0c252fc06bb..d28d53fd6fee009c4c2914d25fc64f08fc357cb9 100644 GIT binary patch literal 2836 zcmeH}c~sL^7RN!x+7To(Wfakg*m}e>MWqMBgKP;HNsvI&ib5@7 zwJsoAMkqvxG1MSSSb_}_TTB8I2(lzWD1ngt!um@>$THFSd;ajxIj85`_s=`;-uvG7 z-OqjR#t9^1%jO-Mt*orJg#9!4q?MI*;Jfkh2FuK`~0L-BN_FH%coy0TuPu+ULayL;e_Qdmsjo( z>^Em1W7fNizWKE55Bq;s;7tLYPWQ%1kB~H~#l=h_kw_w~2RMv7NT{tY_0uF034uV+ zXf#JhM_G4%8qJW1sa_KZ1TS73t&-BCnf`gYMNm0HXx$4#C{EYLP>n_-8`SA^216(O zJOJuJrHs4|4Avr^$4mNLabBSjQN(t_ldWa`Uq`|KZV?3Cne+2m!JU1P6;+j$Ltb2) zY(&HJT(im8S!*aRiSGe(2PjtR3ezVeBDG4T5(b!6;yTH_nW)#`n3m^ExqLh}irLg8 zYAtE3*;T7lDoyEoV0a`?IZ-%myz@xWU8VM%r#J_YC$PS}4&nmV?>F&e;0mFA#9DX? zbuV^`a1Wld{CikeFgBw49+1&bKUL2v8G1dig={jkAN=gUQ7XY$bH5uWJwiZ}%z5!` zdEp|Pi05(PAD1m8OIevPz#*^u?JaPS+0SJD_|$e1)0E}$53`uBeo8TA_tH?*mbh@k z&J8BrQWCru)!_eGOAzq{3#882dcwu86p9p&HduQ+uIQsw*~SVe6go^R%*C6QXZo-5 z`{tB_jWqCQs=UBh*)Yfz+I#&mx!OP!(pQaA*S(Ud$@ zA4~X&AJ=zB?>Z{=Li+`7+O!Fn3&2)2K2taot1--t2vu708lpoY7B4L=Ei#kFN*;K= z&v8xhkTJvR?IgW{PR-A!CMJnQb3^Ny9WOCM(-M0Iiik!ckz+fzH7dWW@accEomB>8 ztQ;USoIIkssx%P4$PVFQV7~+Sy(sw2Xz^L4XM zk9~d04c)DB&aEdZpfThj#jqIJ+0A7I>an0aC~^v~PHs&#|t zAk>;$Ub5zh7l-uxCH#Myfqrw%|IrnVR=e337l7;pVh*qOv zOIr4^acAZ!!jnW%E#imj0E$Tij9VIsY2>1J>EYsM&d$ywVPXuo?y=o`AZ)zzzU;C5_(^3RMk?F7 zN|Wq3l2l~-#;?BLzq~(pz&_8dxO5tR5&17BXVe0u-g`I_FP+@(y3iKrF)J?LhIhb| zH{qn63M!%NR%_go#sEN!V(r$tP8LC&{qyzBi7o+ox`E0-G^JF2{3Z&8Dk=c=zRNGO z<>~oGkN6A$19m{}A~)EV<5DPQQ+~(GM!g7Y^t8Ri*|00oNiZa5RZ1ay1uiI0yXZ{^9s}~ZA;d8=HP_+M*akEaPdg7xFw*c;a*Q;F1 zWlurvk$_5d87}ag$jUM1c^u|mm{m28Gro4fV~5@~D3Td5pb7alSOw+w z`qoUpnj};EUA7%vSi?W7jhw(VeFgWYm<&@>HTJ6+Q!BGV&^^5^iEp+%0~!OS>aEU) zHWn8B?1s+>J(0tPHMq{U;$&XT3p^eVuqTSBc}iN$yTAvYr7GsH)=Bh&^4ex^^KPyCWJL^x=$n|(IJ^^Q-q41D`}(G~?%b|!>p6+{ zDgfeLM|&%kQTM&}wZqotNMy1U%eLo#`|jkV9gFCr*@wUh~{x`R!VTg&>2U9y@#WKVolN#{d8T literal 32694 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
    Na!?g#zaCx>U0-n#XXB>P4S}}G%Ic^L%^Q#dP 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 t}GGUV6elT zZ5?ivC_t}|8Ugs{v6KKo@evn2>a-Gi^>zAWm4Wj~-T^n69O*?943QwI1z+J;^kh*2 z5*t|1p+k3O(7!=UWM$7*ae6_W3fM#o1f)CeNS%E)tJR!i>Qv#v3*{GHuo~|rL9VZA zl*p$XK2(Q*{{|o18BHwf8p!{5I75!bDmw=21n@z~!5FVW{RPU080a_x zD$SOYshR*jfn8+h*rETxYwPH_i7}6;X8~i>EnB4d^Mxy~6fU^H*w-5*ea<<;#TSd$ zTq8g6gg#JkHwllqr>ncGt=)@&M@R{xAT)-O&HeOXMlqz|vyAQYsvL7i5=Rq&ihwop z$VrAk28nZg=i_JtH1bt_VnCStl)-gkM+)W6MzO<~=cJ?El}dkn`8X{E>;*<@#Dsl{ zZm}+y-8;`ndX-@9qiY*e-urT;gL*FdtQ(L5M%f3-=4YgEM#;J=(2ro#3SM+UY4c<} zAtkbLuk)))VN$@w0~+q>?Cxl3^L2SRkzh?!Top{Bgi1Ub<7QLxVwC24qYc*q4a8$~ z&dEhcU4enc^(6Vy7@)eJs#~?HrBcT{Y;Mf sTJ49#jv?vhnE&|3`RL~|1i--m1LRS!ZV8xS4gdfE07*qoM6N<$f~6I`AOHXW diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html index 5eb8ce0..a4e9178 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png index 67f0756412f30c8755f06db0b43d5a57559815b8..2118a1dd3503f221f7315f7d5eb7813db7ff241d 100644 GIT binary patch literal 21825 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 literal 15339 zcmeIZRa6~K5G|bG4nc#vy9akCxH|+6?(V@gxVr{-cXtc!?(PQ;9N_X@dHJ92^S|!H ztXXTOXS$}krmAc2st6?oDP#mZgfCydAj?RLt9<$LRrtRH4&w8Q=pEbJmoI$vGU6g? z9tM}$upXF;YrjR}qx7qx@wMPp)Ri!yL@?=r)*S|Xc{`|)Dua^OUG8vQ)J142($d$y z-q-96oFP!?z1|=8ZYir{lTi&!eiso(LWm|IgMpSr`xXR29v&_d@J)O$uNRKYL}>?*SUC#jx_f%Z-@0r% zYbsglVZXakTNx077kS72ylq4=MeY`J(S4SDZvJS)eyRMoF?01Ypja$4%>Szt2!~|U z3Q82D@PFy$QJ;%{>};ehhN2Gy38*V}jZ0<5vmel1ecZ`R}MTEEW} zIx-9;NyWhYL6evA`fn~@)Y20gNipv49kXQI1PlTJW-f8oiW{%t@^5Ge&JPo)Hk-U& zky-0SYf(+e6ehWxW5Z~YROHXciS*wK{w@AKtcISs`9IHYYIHKVa2mCl&kDZ}!8xr8 z2L$a+Wfz82!!XR)dF1-D2I_Gs?c{~0{&m}N*|Ml?%wBT!ekc9kW0~bcHq}xe)VGHe z;r|>a!=|DH+*^+~XDQ^W={DBSQ5|n1is)csK0~NwL{%WAFP3Ww7)WV zE|ZZl+^=6A=?3*6Un-cr>Fn0tT!)h|!Xj+YBrn~uD>E-+GZ;Ue*o0P37aOI8m4BW|RD^Qm{Ae!JCn zE0GZJ*lKo#A)wLS&R|Rb1eMr#;?%a1iq>`hYr8!5qewQlkLOd;FPLeH$%2;`yT=OS zz*}I)W=`dvRVk{NWR(g{g-bV6qWT(Uc*|mj_zOWQpKkuDTDd&0S7m4G!qjZ*c#>i2 z!(n>bvch;>GNL7`l95nyF#6pVf~flL4k{AGCDwiO!ew~1AU;o#4(?@b;xX_M%6|7> z`iW*QsK-r6&ulU@wGCI>S4H-ffO#uBd8PwiNu*rST%HFX&VmZmaMhHksF$0D~cKkuVpe?0n_5r^R zD1_hO!{E#k(DA>3l!At1(mt4R%dEP6^KB=wzK~q@GCQ^8}DY@{f zit(0)gEEF2a)5=KxPj~wiY5twQx3>S_vZaoKO%F73g^Hp&{I=J&0+R}cbIok(I zAP2=Dl-sJJ+1uBzi9J1zSxm8_x~{ygK220a2IZJ8_4=yKSmjgiiF&|K8~5(qY$nMD zUc=h|1T<}?+ch*W=O;`Gkg_n9|MfstYxpz);{m}yIC#bYYgz8)B%7UU+bnd?!@fbh z@L+TDQ-x`w7fY6^?XoP~#YplE_S1vab(oZ{DnrS2bzoMH2 z2lrwX!IW1vLCb+)GoaMooNc>iRg_gbtD7CtN7gxp;Pg`Y%jfh41wbz2T2XY49?v+a z%tZf;0pHh$*ldQPX6#>{|1cVwWg=N~Y5>8%V^i@8WpkB@Kj0l7l4(z4V`VSFj}aZ| zcXB{smmh;|XV7k%D}SgdJJNGhrXbYR&*%hPTnIIGi#C7VnR_Wto_E@PZ!T~(j>@s) zF3haWAAD3qY(s%x{)Kf{oxH+7FELy6dhiLELs(2PRG z;t0u^hR%4odR?*x{Ix}#yrE$U`|NHD({2OZFQ#jnYe!{q8K2j5f#A8jadzu1xuhb% zDuKN3_dMzGQf>$PMW}m(ZDa}up?6Pd8dAIfdcwJ$NTO#$yY-L5=G~MYge!h>&$|A@ z358GZ`myPBzbZDPRGfx6H*ct-HuEgDdqM!Tiu{3oM#u2P zg!kiUlz5U-UP>;uMHfy6>amq(#wAJjD`0&1?)E=zi4s6)u0?%hx)&`iVXT~wmy+y%H8;_1?-M-#`H{_=vkEx*!F=OI z-+#9;jEbd_zJ96DyoQSRwzXFI4y>YDQF|X4yWPrEt4ZT<9Cz*e7ArU{wTt+h_*t*wbGS=Bz7vFh`n(cJVo z_seyZjscs3D%F)Yv{nrvMT^SX zEP6kAEn++DWGGunlc9UP1+kSE=_>zJkirbZ6 zH_SEzL@SE!Xkuu}a6Z+g6-t`MAp7?}CCS@tskK4gbXgiJ)s18Pb~u|+g&sePi!X}E zAhP(gUm&xTh@Y7M)$8D@S4C15e%Mdwyio6$g4}*!SoNrMMEjsC&0<71pxV_o0jZz+y^ox}zX5U!;5u8{j9xMHPv z;~@Xg^NQ|@eEmLlbO)?)=^*q68++e~tRr*ZbYZ2O*H9CAjo!XqKR{YjsC^6Q{g~)b zII-$=YJNDS^BpeRSap@bY3NT|8ddYPR4|vX))22}ZX+!5n2Gx`C*qp6C}+V?^Puy_ zTSLxa+{Eg>Wlb`-2xIl^uouJkT)?FrzHVP);5CM!hyUH_krW~z)58AeQTXVdfmOQ*JE5AmwsCp9Z{Ct5;g_X~3t>vsM3KqP7ioy5KLvK%*@l7aukHn5^;iKAUs-WPFq*DnPbrEX4S}ke|O1cxQ@OpylvBry?vi zBBN&Mu)W|U&v#)mR~Ocif-7)S-KyFes|#a zv7KyL&o>)y|xqlei@%ddadfh}na5gi$IJ2(PwKCIZEwM|5IzFvjy2K*(TW%={ z`uPB6>Zsf0Cr^?~5j8F7ajt(PD{D;&cm^%GS({v)T)w?r63nqO6`cQ-(j?Zq)z=#i zj$ZlWEwo`zu||~Yr(ABHgFE{pTO2XO@GqMCR)jCVD8ek^nE54rE7-YogfWm^J~ zYvc@5`=DuW4{pVJb@O>*ud={}VO^T4fugZAUTIC+hEyfRgo?yP@tbyHsmK^kQ-S13q##=0TxonU~ zgRZTchN-8Ywy>Gm15owNC1_(?sR)`9+Ce0-NK~fv5mQu8xg%zH3Z8kBAVv5m8Z? zTlh+Mu3v&9ztNJIJq--Npzk7wz!^P5P4fhjRghitK@~yfg|ml?PHM!eBD~a`nA=TP z@bu+;qvcDuaV7^<$He=3#P*56;T`0CBSmhRaiHfFj35zLK8Y&z`Ev^OwW9J-?p3+bYW)xx0~1nW z&)_a0r$utMfNVQ=wO`~rK|4mGKYc=b_7?&RP=g^FrY7VK4?}iKVjY<*19K^dRmS0Q zpVJ!cHt^rmR$+q;&-G7`Xas;~4;N2=kC6=xz#)!GLjNtzXx}>n;s0Ej)WG$hLa&Ec zw2c%o3f{k|Z`SJTCY9UNppWSrkzXu1`%=wZpgnZ9$`eO^^iqOY#3k?Kl z3%R{%z^SmopRzhKX!n1ZjxI)xLWO2fY)-EG>=am@pOuC}K<>_sZIls_>aZp228}(A zoT;jC_EbpzGF>H5J#gb+*5V3)31Vo;^%gK_^TEmHW4!nhEdKugHm%G{Vi z>%>XQ7Qk&_1O0=liRuhWKN&0GS7c81N2q&7E9%O)t=@}F1e=z3z@yGNFXLOKg)Hz( zey=m)c7RyoT@PXIY?OOxku_|0aH>kX`!bC>7&T0wFPEF^L{6(_%JXrb$V5id2f9X zv{|08S0x71KDuTuo;kH0nft$p0i*Z>{AUPtwi-O=PdGFtyS&zCj%Q@k`!~ToSY*87 zR5ud*VzQHho+N$T%HH!yqx6K+2sB_woW0rzy%S$qs98nhIH_?rW@eCy-qJsb5MnIt z1V5Sg5S}WnWKJgAofc}a`c-@xs=NX*39~GTU5`GEX#>LTjDNd2U6oFua@pp?KC^qT zgf87iGkbjtzg_g4COjF2hmbjEkP)20=)p$fXR^*Jc3TP9CeJ0&uE?kF<)VMvPbi*X z;G9oftMB2A?!|Hwvpu?AFQC30dwD*d?A~W~0$h1S7I;{bEKO_)Xo9t>jCtIt$qdA)9Gufz7F#4&p=CyS$J}m= zQokW5U|CJ%uobV0w}?u~lEYD7BGKP03=%68#|UA7`enwh7$U%F>4C)Idz}yo6iq10 z!22jHJo8D4t9Ch>V`xOZL#@UWu=(v*VoBOWJ_3}|$p%l?VpZTa82^K=_1p&Z1*u;X z)&%`~_tn%Hbhffq7d^0l>^`S;?RgSLpEINBrextNtE4drO^_IvbY;vXyd&%Es6VHP z`1G(W=f=v1?De)}(iT>oKCfM!U0*Y&b-6Xpe!)_yEyw?WHd~$jZ?3mkpYQAnfAbu` z%6)j)p+Rp3l+Rl~DWA*Qpd-UX;2q|t4J5{cw0_<$p z#>UR5DD?B;Y{*?*DV#`P^ef~BZJjwejPnS~{qLKKxN#1;WC@}^1-S=J5$gY?04;z! zZ_w3HoyY6xUq0o4lDe|5FVbA}{xItUQN@!OMxk%G>@$Pi+NsYVNlW;KcJrmu&yBjJK>76a0t{s#InB^Vksan_d|;9g|+ zJi3^;eF<>gA`R{{YFXcfg;p_>+)1qWHIM1^pgG%=#m}Z_aNRLcz0EpUmB+xzOQ2tN z4u0|&!LpmxTC8)-<96?1B4s^1rX7wIA`L@kf4Wwzu>oHD^SwV0WarLgefgTDZB+J| zlUk`GJ?Ri}{+;s2+L$$BV*S((va>xpB)|&K;k3{`{%w@t_Hh;IFT&DF!xEfF_lqnkjfu z)&-+u+9{Nl^_LodZVk%c^K=(fr8diyK4*@wqaXAe2W<%~)m`6%Yw!jsZWMf#RE?`v ze9My>CLvG@i}z++ACEP^9Q|VZ4(h-Qh$&TIV|3l>KDn*l0AVR?$0BMPHOvl*O9Pc_ zM|5d7ZAn@SGYEJ2Y@dXjT#yBHtHKn%a%@D{kP6nwOSicCEnwk~TpbiFp9#Ot)BbvI z>HgWY*5iRESL`#l3jTt~AciKWzM@!@Ux5Tj95ZR=XnBv-a~z~_V3AHrK1a>jyFPSa zsgqoKMhh{b>wQqW)&Z4WoPJtcaS^kA$t}0Ysf=${;1W`&e#Kqv^D%-Ar!EH-`|Cq^ zU!9ADhe2DisuYP06kooNvAoZ%IeE4>uujU8MbY;&ugV&~>59iMXpu#>)8xf6m-9ln zJcKsphVqQUqJw_WyGOuMjoo1!3T+hq6sPiX-kp-l|LsSMBBXso=&=n z%2>vC5RrPq{d=}Tc<}~yrJk={ejOTSi1hT&=MpMK*IYxosr|*wREZ8+uOzG|4WgP9 z8}8_XWc*0!u%-2hNN*IxEciJUY(g*$>pGKtO%gAt#2?F*2WS2-FqSKsxY1E?b$GVw zPoXuw)C|{EpDmqWd%hR2(9U)zW*aR<1du?HZkn@9T{INI@Q1khQ0R%-@9HXK#?653 zq}Vo>I9cx?t1myu0*Z^5nLqQQ9kS$Z0-}YVzA-tDN9=u4sJCy|qWnzHlD0yQ$d&2^ z%WYM;R`b*$)EWJCfHJHJV2J-+bB71lS*;l+!DepNC)Pii&fWN1gLA_)0Gne$ga*d` za^0OtMSC)7Gw)s~#3UfwDnx}To(FH~y&^m*5s}y#X!*-Oj;YxiG*fUgqP*Nfetj-2 z_}==fFOVvfEO0=ckKh3M#sE{stAyS%J!xGy&8x=mtvx;Vb}8hXrNX?&)gE8w{XzmR z>hmLbHtD2P4RMmYoepz)#~Q>X+?|@aiL!9bo}E*hfUX=DZ*0$! z$1l#pmP*ovYOJm{!@65PDBPXu-y(F&V5>1?@mm}16V&Ivp0`Gjt40#8!4e!0h-9jeB)X000dMk?f;|4`r$*h0FakoY z>elH0A>@kBji0F5ZCI)iyMCU)*6DTHw5|-ADZi`j<}pHr z8-SLIMXD6ZH1XGrniU5K{Z>B}q&W}@SZTyt26(c8GeXqF7p5J58Mo&UQ}FFb+TC1J zlW(tlM0TVGPaRm)ErzY0ojFr(oKG8Gkn&zzW(q#V#MIB8&h^>BDL;B$R;G2i; z{!CmRpu@#Hh*A{SZJ5KV3GG>S7B_EQUA6nt<{)k!H<4aCHzkf{tIn$d?20 z?K@f9hitD^affm9sFz&J#-5h6qSdAf3$7qIoAe_#DtcOGCb;LUw(8^C8D4E?lQqXj zOn5ky9nvWG&!sQ1A$xO*R}t3b?AWNudOEs|d;f7CpYXc_M=hDrqFqpb9Gxb6gF`I` zRc*;`B8703Qp$HT-lZHV-6z$GSv&d!uTDtF)$EPFE|iwn8I!{dNc^yB z@J$3K`Ock6VKk38GU1v@RI+H>Db;ab(8X&r=1n0vBR%XNk)2P53a1^f)v?0N-q4;aKj zbR^T6Ig$CeuTR~W#kw<|2+=w*`81Grx%?pLcz~)IQfS%a&WSK~>MviP<_7C=@7GO7 z!DiA#{W??A4a3ehMszxjA>5?wR@h7p^2SEN{1k`3(S_#2L|hyK_CiWV2`kE-Lpq00 zVWyMOb*xPU9!Z9+XgrQZGdYy+!be$zVwWAi7H4jahMcsC4-{*AdGx)lM~v+n@*{(P z(X~6b(D}akgWx&+3Hq{e2bT+_Vp~L>xxpP8jTY#CcxDn+341y0uu@B^H_?j-uGjg9>o$61tWL2CvR*qC5!D*m! ztN(+*0Ce105;MX6j6-hn?YT5vg{u;SH=9U0r!9RmCQZjP5%PCMv-Cf z&=T5}7<2Qq`~>Y_SHrm{+yF^ zf4<~M$IN4cS9ilJ-xVPW?%3UZm$>{n_)TDIUEnB%C-$DH=VJsmWUoofa(zkAlkN4Z zPKr6i8F6TwA=N;Hgzwk3@DUPu7844kg`a7Jeph)wkYf zBt4w8WZtiw1V8&&`!g01hVB?@w*_w=9WDxAFV-OT7`rnQ^b!cfbr6fv>-`Y2oZ3Xp zeH*#ha-Z}+yBENC;A($4(1FcA67XKiI;3*Im0kJ->oQ_e{bQSxzSzzv^ly(+rl6s3Ed%TsE` zns5|=|KU2ZLG9tczJ4skX*5q=f%)gXN9^;X7Bmf4tJ@@bJQ3WfGymIZKw*_8HcS|( zHon*l=BcjE(_j2~_rTyHyYz_E6BTkP4!h1)Ocr<;Jb6fpc~|X6+d(kIN`G_V$q2pRl<)S>_Rs-tG`7kI6x6k! z1^_`JVr}1e^7YTPLpSS0WS*=PTrZ3{cQYs5fwjQDaH(-Z@A-_>f7mv)InNOJRW}<& zjI5rh*(1fR4ogU~&qN|P-|ZE~iZU@Gbu#SicFBe6v6D{{`{D3+(5Cx|A}$_fOYj-* z1EIl3htqN}T|Hqr4YD+~QcBK%I-Z~G_lDVVpda>>u+7m5z8>bcE~7IMVZ_+uZafH_ zCQu)$@A}|0)7V?&RZ+Zu<s|Ln+taSopr-Bxfy1&mi74r6{k6N(hzLmhEd+gmomrAYNu7 z%;vkH!_#+Cgy_giz|F{@2pUo2gX@n6>+u=|oR1*egN=ZR@q`*`GXchj6kQS&YO5B5 zmvR&l?0S2{_Y!aiO@hXw{=S~~3B*8~SlkkQ?YdFz=7oJ4=~WjFkYU?*?X(C#3z702 z=2$ip>@vRc$zb!-TDwdmFri6rZwmm+T(3LZoYfMNuE^|5F06_X3LG`c?cX(F!lKqR z1P{X=whC1{qWK-S-OEtl443|?1%2o@V}XwPNVCL?I3T#}GUmgmZ>HwGecSyZ2z1h# zgiU}|exvoY&KUNnN&vasTmcRG}T6*s#;8~SFBZoovuXojG{g!E8 z6O|307I(C)MH^biJ6C+QF|0AO*FLR$_U)prSKaA*C6SQ%n2MNGPaG9m&Q!qZ3Br0N zpVU2+pUsfNUnX}gr)Oc%*AJ;%be0g5RQYbBXR~qQRc7tArhj{(ICQ3|OkmWPCvU8+*xNIdB*C$zt2i9;^bHz&|U55S_L3FuFv!Z> z(^rJlGRorzBLyb=F@r2+P8s|rrUUAtp8t`o`5ChDm{7*jLl~5|2;>5C4WcFO?z_Ei z?CpKo>k8*D|2n@SD%vz^S2@f$`L2Q|L3AMrxJ=efTD#^Z_E$uuLe^>zG={C2s}{kE zZ1mp2H-wNWb(Z=+3E!ClYAm1tX^Cf9*dZb-iuX`k+GyXJ_lo&&9(vqodxvv;8sQGC zYv6l?m#k}4qn{O<*k0r(&p*j>^^7P`DzwNl7V{k$MG|SI5G^Bvf}&tN8ix75(`4Dz zvVAv9 zvcDo2B1qQOoizRAuXbC)Xq7NR+gZJ-Jo@1vk63mQ_rBwAK-fL#+-4~4km3sgHiB%h zuW(J@?lUpm?dgbNiT6wQPF}!|?;l_6Tab_AEy&HH<3}7y$`NR4?|l@Ru}dL8(q?s^ zWBS=Ry&X<#?fQk(CQ_Si3Ga{Z1&@;p7EU~!Q|Bd3m^KLluG6*+pBJwij{cbOOc-o_ zj5qM*%BWE4d&xv?TXp|2d_BZ=KAvt57MGE+bTkN%EQ7E#*41G8`cw%(>@@XaTkn$F zM>sZJ)BQfxY{YsP1Fa}VM9Q3c1TgJG&KKpQViaCi?`0$Zz(N(c=@nqLBzw}&idUW- zu1?67?8?cGQ>VGfnG<-x)JE2%U}`A-NPkMWxePY5ns$yy>_LA|*6I8Q8N{rsSQ%xc z7-4;oGr>Kn%)udMwEJC+rpEpQW^WR>cZreUcVOtC92W!w-y?wBEwijI)ukY$fdz3D zKsSl`2at$s8Y*z3Qmn+*#Yr-0rG9qV7Di$ode(b+|I*du+^EJFG^&@Do#_V-E^3Uf z{kB~!K%+)!l%8{qU&PDknsEfi==j|5Rktk*hTF5a)3F>VibziHi3xrj%w+?iYjyRbxic&tbUs<%qJCC zd-F4$jrXxHyIyFw1Ve%9^$F)wul0J~Rc|fZ&%||DH^vmnal~`Uy8t+w0tQqD+_`r! z153-)`RjSz5IB+Pk5Nzf<=Qvq&fcznR&@tO=GX^EtmoQd?+jVhb(VQ#Ui?hmouyD* zfWsatOi3*&(}#d@Iz2fa+8Y)XynJ%k>JzOiTaj7F!&iYV*ohna0y;=z?~mh2zh5c? ze&aqSURx86XRbu{%kko75Z-v8=l%X3m5C(aWwu<(vyc)!x$e2AeMwY(m_?ArJydrk znj(MS#~Ft~9u-oPS$K+k1IC9zz;Ai{y@na9V%hy{XY!pU5^yfhz<)$DaT{|b!&?TA zkal)uEiH+s!YaqSG^o6Tp+nBSp~1Ls{f*!W1Dqrr^QBLtfZ3c96UEPDMO$9pmV&yh9&(z9X`C)e*9tLxnI% z(278?RKB=XmU)WH^8D0=Mj=z4>_ROY>;7*32&(Iotuj?Pn&0M_!?pI&*~aCmv6LB0 z*i-CLL=8GSIk+%apqO@TCE$yEYnWj@IKRh`MJJKr!j0x_0;m+&!=QdCAE92Lo#e7N z#>7VZZsL7cFt*WFRu~y0{Rp;O1V&)Ab&cp2p}B7!GBF=_DbpW>iNA&h8y$b?$*>@V z=-4#9-s-nkoDZ?s&hY_iQ~kg^IA9g~mImF*^sN=XOCzn^)NM&u$n1g8w?9`waoo$w zu5bPRPH0WFefM<%##a9$^;YX|{MDt+tpYvruxNCX_cG;*vN$(qpCaVNuAmGZd#ah2 zw~}`!yF|mQHd`Yu<=+Gg?MA`*p2mbRI|Tm7l|wREl;CL1=a%--xw=An-i!~Xs$_Q* z<}rtI&dUH# zNWl=$swX7ihxrF2cLF$kWgV^l>Tc(VUgkhOGAtDIoCHoKnwuHzhwxQjvsbuJ?l?{? zK}_DcE-WX}m#qUC7&!2Lj|Y*?zL4wuz@y}H-cpL?QY;{s3T>ReiVe}jU>EfDo$A2% z3I0Q`59e9Hb%@JC0S7vQZdrm+|61a!3`0wgT0Ezx{7a#pch666iy9v) zXG|!-00U&Egt=vd#&NYtvtp@g>n6X)qS0t>Q!qANZ>{Z<8)(b0S#f22svr1d;y}P_ zdbyf-vCh5HG;P=M$LHYNal30(=M*R~njf&8LO|EWSKZm`4+%&tW1&`b?nd#P6`o4W z>>yH_1ob?OeE0UBJQ1M$CEPZdiYkUM^$>4r3>`Y?Av^9@z&501{?eL9lhPdATWAtGdH36kJv1q6Jdp-*KIqxw!F{aFHi{P#Qua}#n> zQqICrs}=7Wt4axUTsT;!woa?Y=dTSa-^^<-RO zTnwdFkym(1gSc;ed_c0&mr>7Z#eo1g=5qi>ikQngM$ zqmdpZ^d1DvP9{?DNyM7&NLt3aqhWy&w?v@;88!S{-Amr}?(7)19(dK@{{E?4{Vf!$ ztRPZZ7nsMr@pM#1{FmOjaD`aAOXe}N(uOAe6w8C=K+ z4O0&p5U8l$)>TM0f|GDa*W8o(dSBpnUT&muAh(Mv6(?NuQ3b27d-(C*r&H4oz47*&+Wzh z#xlZgWt1^6l6+O#X}UCQ%00#B8A&Nw>KYJIJP2;@MS39DNJVs7`27n%1BO9;{6Ky% z$N?eQcvuV28W^*{dM^RV)Dq<>h?K)F7XX{3+FV+BV+86ebTX`5(GsqaJK?|!d27^4 z6G=isTX8&6&wDM`^Z<&Uc6zXU@W%&1yw+tf4na%c%x2;R=2YtSKYV9hpR&0rqCRI! zZ^p9wB}LAOX2x#5MTy;zo+*?F6>6Aq z%%lDgTLG21U2s|(5e z4s)rUly-W*H+sS4Oih(?%3?JP?i!C7rw=`0?6|dYo7ow++>~3|qTGfec)1lb zKNpMYUm3S}Uibr%R!v#z6_YEm5xE5Kf2cXR{QDc*UiJOm>Nz#_7s@?73WASuUZi!t zxu0$MWh!C=0O6E^8|wv!32|m?n7{lGVG`-Qm}b26$!y4Z-aIu!E}QB2sDJ9B>9^Z9 z>0gvd@6f@QjSbVUZM>hY75$e^$vCOy2VaLbV4>=@+r)LO82%)Hta?VEp z6%T_h@7{4pqKG8CMRe6!A&*b}EEvEBFhLb-2kgQ^pg*d&RiG!q>xd$%TNtP|=oWrs z+WF#`Y1tGw;VBj$hxQfPj?1V4CwWDz&X9`q4n%X8g@<(qYidgi47_@ z#6)p@#0Yh}fSq(_$YukF1f~4lq-~R30S_MhH>I5@D7s-v=#YAnVF`?j5a_+MWw2`cr+27<_346ZVXy}Hc>cg2S?a1}- zO03`pN!68G$iZyVK%cslQ*r*xOi4=p!D>vVxkEdqn&c(nQD+aZ+zOPLrfEM;37gk~ z2C+Bz_PI+{f41ph_gb(dVPkXZv&N(jjT}gbw1$#gxbTsB<`8gux<}OH!kki+P$+I? z_UKmKbF(>jaI9BqM2$@n-cI0m#|Bf;ILMJP(l3|e{R!iX?01f8*f({Ip9`ndj@sq} zZ#{kcMK+FNPq*?z&=K5S?<;j!H>qU;W5=oMP62b)yJ0RZA7+l!LyCg1(QmP66{oaf za&e1tPUz~g@K1lneVqXK+$?CE+23yOcTti?40}zq;5uI@&;m5&wX8Ev;gd+Qo#09! zNo!{ccKmzauqYa41|*<>5(!{N#49c*p`KCTlrGn|TVCsI>S_Vv;XY2KDjN#6ytZ+p zbmtULWYzoc;dl#WdiWH~OIRCfs3l}bE9zP{tfk?)?Ff$Px(`Z?Pz@6#C(9)}Nyv&O zXcQ~R$pWN6OYg`~xXGqio{W~BDZk|qpWDmOnnc#Oi@^!dmyW)GRMEl<8lGd!eoW%`Ywp9P_Ycl(~=*1kTFhM~GM z7+yUnkd0*rVZ&=H?ew7bOA2p(H*q?q4Dy7W`rxVAe)S%HQFQ%r!48Ov6}0l+`T8zD z{h3N{cv3&UoZB&m8bU$8uLq1@KC*k?LWSNvfKD?uyaeD$pG2**Fzbxj`f~JYgfC%cqByfwI&Qa{5(DXF5d+ICgcAWuI9`2CD8=N^Si_h zB|Tdec2t|c|2pULjf8Chc%OJ08N4VT|L-ewH$)oEgl|+%2N0YzETUZnl zv$bg_I-;)0mOhC+?LSof6u8)41>yOLp|7~DjEJy0i zv`!_y|KBzT{$KVG{=Z@WpQg(Hr;z`jCCodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png index b7c6eef5274366b574dd2b0afc271bf91a85a8ac..69d0377d41f707c176de778296c6d5d1292d71c3 100644 GIT binary patch literal 24091 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 EKPn1Wu>b%7 literal 25932 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 Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.png new file mode 100644 index 0000000000000000000000000000000000000000..a35f4c002a42681c71435df2a37ffc0b91dc609b GIT binary patch literal 9958 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 JTF&Cre*uwFDI)*? literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html index 2513fd3..154f96a 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png index 93b066fcb694309f832fd4ed79974bd1a89085a5..7dde07f1fceb14eaced91c600383cab7c9aadae4 100644 GIT binary patch literal 9299 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 WmCT9u!TwnYpsJ*$SR-#4`hNg9h5;l1 literal 10401 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 Date: Mon, 28 Sep 2026 19:21:39 +0200 Subject: [PATCH 73/75] codemr inheritance tree for 1.3.9... --- .../codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr index 63b70f1..d298d91 100644 --- a/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr +++ b/SerialX-core/codemr/serialx-core/graphs/all_nm_inheritance 1.3.9.cmr @@ -1 +1 @@ -{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":20},{"@type":"int","id":"#edges","v":19},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":398.0,"y":520.0},"B":{"x":547.0,"y":50.0},"C":{"x":398.0,"y":441.0},"D":{"x":392.0,"y":278.0},"E":{"x":249.0,"y":247.0},"G":{"x":547.0,"y":222.0},"J":{"x":354.0,"y":52.0},"K":{"x":397.0,"y":359.0},"L":{"x":545.0,"y":183.0},"M":{"x":60.0,"y":54.0},"m":{"x":549.0,"y":269.0},"N":{"x":397.0,"y":399.0},"O":{"x":50.0,"y":320.0},"P":{"x":394.0,"y":214.0},"Q":{"x":548.0,"y":88.0},"r":{"x":399.0,"y":480.0},"s":{"x":217.0,"y":52.0},"t":{"x":249.0,"y":413.0},"x":{"x":552.0,"y":322.0},"y":{"x":545.0,"y":131.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"J":1,"K":1,"L":1,"M":1,"m":1,"N":1,"O":1,"P":1,"Q":1,"r":1,"s":1,"t":1,"x":1,"y":1}}} \ No newline at end of file +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":20},{"@type":"int","id":"#edges","v":19},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":400.0,"y":481.0},"B":{"x":547.0,"y":50.0},"C":{"x":399.0,"y":410.0},"D":{"x":392.0,"y":248.0},"E":{"x":249.0,"y":247.0},"G":{"x":547.0,"y":222.0},"J":{"x":357.0,"y":58.0},"K":{"x":397.0,"y":332.0},"L":{"x":545.0,"y":183.0},"M":{"x":61.0,"y":55.0},"m":{"x":549.0,"y":269.0},"N":{"x":398.0,"y":371.0},"O":{"x":50.0,"y":320.0},"P":{"x":391.0,"y":187.0},"Q":{"x":548.0,"y":88.0},"r":{"x":399.0,"y":446.0},"s":{"x":221.0,"y":57.0},"t":{"x":244.0,"y":373.0},"x":{"x":552.0,"y":322.0},"y":{"x":545.0,"y":131.0}},"vList":[{"type":"y"},{"type":"B"},{"type":"E"},{"type":"M"},{"type":"N"},{"type":"x"},{"type":"D"},{"type":"Q"},{"type":"K"},{"type":"L"},{"type":"J"},{"type":"O"},{"type":"G"},{"type":"A"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"P"},{"type":"C"},{"type":"s"}],"eList":[{"L":[{"s":"C","d":"t","k":2,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"P","k":3,"w":1}]},{"L":[{"s":"t","d":"O","k":2,"w":1}]},{"L":[{"s":"Q","d":"P","k":3,"w":1}]},{"L":[{"s":"J","d":"s","k":2,"w":1}]},{"L":[{"s":"G","d":"P","k":3,"w":1}]},{"L":[{"s":"N","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"P","k":3,"w":1}]},{"L":[{"s":"x","d":"P","k":3,"w":1}]},{"L":[{"s":"E","d":"P","k":3,"w":1}]},{"L":[{"s":"L","d":"P","k":3,"w":1}]},{"L":[{"s":"K","d":"t","k":2,"w":1}]},{"L":[{"s":"P","d":"E","k":3,"w":1}]},{"L":[{"s":"B","d":"P","k":3,"w":1}]},{"L":[{"s":"D","d":"E","k":3,"w":1}]},{"L":[{"s":"E","d":"O","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":2,"w":1}]}],"clusterMap":{"A":1,"B":1,"C":1,"D":1,"E":1,"G":1,"J":1,"K":1,"L":1,"M":1,"m":1,"N":1,"O":1,"P":1,"Q":1,"r":1,"s":1,"t":1,"x":1,"y":1}}} \ No newline at end of file From 61abbae8eee058ffd09b58655caf7bcd54466de0 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Mon, 28 Sep 2026 21:44:27 +0200 Subject: [PATCH 74/75] Splitting Utils to MetaprogrammingUtils and StrUtils Deprecating MetaprogrammingUtils.post --- .../graphs/all_bymodularity.cmr | 1 + .../graphs/all_bypackage.cmr | 1 + .../graphs/all_byprojectmodule.cmr | 1 + .../graphs/all_nm.cmr | 1 + .../graphs/all_nm_inheritance.cmr | 1 + .../html/graph_htmls/all_bymodularity.html | 1 + .../html/graph_htmls/all_bymodularity.png | Bin 0 -> 22760 bytes .../html/graph_htmls/all_bypackage.html | 1 + .../html/graph_htmls/all_bypackage.png | Bin 0 -> 29302 bytes .../html/graph_htmls/all_byprojectmodule.html | 1 + .../html/graph_htmls/all_byprojectmodule.png | Bin 0 -> 16412 bytes .../html/graph_htmls/all_nm.html | 1 + .../html/graph_htmls/all_nm.png | Bin 0 -> 26944 bytes .../html/graph_htmls/all_nm_inheritance.html | 1 + .../html/graph_htmls/all_nm_inheritance.png | Bin 0 -> 10186 bytes .../html/graph_htmls/graphlist.js | 1 + .../htmlx/Xdonut.html | 107 + .../htmlx/circlepack.html | 113 + .../htmlx/dependency.html | 31 + .../html_report_serialx-core/htmlx/donut.html | 179 + .../htmlx/donutcharts.html | 42 + .../htmlx/donutchartssimple.html | 26 + .../htmlx/lbd/README.md | 109 + .../htmlx/lbd/dashboard.html | 334 + .../htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../htmlx/lbd/notifications.html | 310 + .../htmlx/lbd/table.html | 446 + .../htmlx/lbd/template.html | 154 + .../htmlx/metricchartmethod.html | 27 + .../htmlx/metricchartpackage.html | 25 + .../htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 17 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 231 + .../htmlx/modeldata/table_data.js | 1 + .../htmlx/report.html | 28 + .../htmlx/reportforprint.html | 28 + .../htmlx/sunburst.html | 106 + .../htmlx/treemap.html | 56 + .../html/html_report_serialx-core/index.html | 1 + .../html/assets/css/animate.min.css | 6 + .../html/assets/css/bootstrap.min.css | 5 + .../html/main_report/html/assets/css/demo.css | 61 + .../html/assets/css/font-awesome.min.css | 4 + .../main_report/html/assets/css/helptip.css | 148 + .../assets/css/light-bootstrap-dashboard.css | 3393 ++++++ .../html/assets/css/pe-icon-7-stroke.css | 632 ++ .../html/assets/fonts/Pe-icon-7-stroke.eot | Bin 0 -> 58680 bytes .../html/assets/fonts/Pe-icon-7-stroke.svg | 212 + .../html/assets/fonts/Pe-icon-7-stroke.ttf | Bin 0 -> 58480 bytes .../html/assets/fonts/Pe-icon-7-stroke.woff | Bin 0 -> 58556 bytes .../html/assets/img/codemr-icon-black-1.png | Bin 0 -> 15510 bytes .../html/assets/img/codemr-white-32.png | Bin 0 -> 1254 bytes .../html/assets/img/default-avatar.png | Bin 0 -> 2864 bytes .../main_report/html/assets/img/favicon.ico | Bin 0 -> 1150 bytes .../html/assets/img/loading-bubbles.svg | 14 + .../html/main_report/html/assets/img/mask.png | Bin 0 -> 756 bytes .../main_report/html/assets/img/new_logo.png | Bin 0 -> 3557 bytes .../main_report/html/assets/img/sidebar-5.jpg | Bin 0 -> 280836 bytes .../js/bootstrap-checkbox-radio-switch.js | 502 + .../html/assets/js/bootstrap-notify.js | 404 + .../html/assets/js/bootstrap-select.js | 438 + .../html/assets/js/bootstrap.min.js | 7 + .../html/assets/js/chartist.min.js | 9 + .../html/main_report/html/assets/js/demo.js | 152 + .../html/assets/js/jquery-1.10.2.js | 9789 +++++++++++++++++ .../assets/js/light-bootstrap-dashboard.js | 159 + .../html/assets/sass/lbd/_alerts.scss | 82 + .../html/assets/sass/lbd/_buttons.scss | 108 + .../html/assets/sass/lbd/_cards.scss | 207 + .../html/assets/sass/lbd/_chartist.scss | 230 + .../sass/lbd/_checkbox-radio-switch.scss | 246 + .../html/assets/sass/lbd/_dropdown.scss | 120 + .../html/assets/sass/lbd/_footers.scss | 77 + .../html/assets/sass/lbd/_inputs.scss | 141 + .../html/assets/sass/lbd/_misc.scss | 62 + .../html/assets/sass/lbd/_mixins.scss | 22 + .../html/assets/sass/lbd/_navbars.scss | 293 + .../html/assets/sass/lbd/_responsive.scss | 413 + .../sass/lbd/_sidebar-and-main-panel.scss | 244 + .../html/assets/sass/lbd/_tables.scss | 57 + .../html/assets/sass/lbd/_typography.scss | 90 + .../html/assets/sass/lbd/_variables.scss | 265 + .../html/assets/sass/lbd/mixins/_buttons.scss | 70 + .../html/assets/sass/lbd/mixins/_cards.scss | 8 + .../assets/sass/lbd/mixins/_chartist.scss | 85 + .../html/assets/sass/lbd/mixins/_icons.scss | 13 + .../html/assets/sass/lbd/mixins/_inputs.scss | 17 + .../html/assets/sass/lbd/mixins/_labels.scss | 21 + .../sass/lbd/mixins/_morphing-buttons.scss | 34 + .../html/assets/sass/lbd/mixins/_navbars.scss | 11 + .../sass/lbd/mixins/_social-buttons.scss | 43 + .../html/assets/sass/lbd/mixins/_tabs.scss | 4 + .../assets/sass/lbd/mixins/_transparency.scss | 20 + .../sass/lbd/mixins/_vendor-prefixes.scss | 189 + .../sass/light-bootstrap-dashboard.scss | 23 + .../main_report/html/css/barchartstyle.css | 1 + .../html/main_report/html/css/graph.css | 1 + .../html/main_report/html/css/helptip.css | 1 + .../html/main_report/html/css/legend.css | 1 + .../html/main_report/html/css/style.css | 1 + .../html/main_report/html/css/treemap.css | 1 + .../html/main_report/html/css/vis.css | 1 + .../font-awesome-4.7.0/css/font-awesome.css | 2337 ++++ .../css/font-awesome.min.css | 4 + .../font-awesome-4.7.0/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../fonts/fontawesome-webfont.svg | 2671 +++++ .../fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../font-awesome-4.7.0/less/animated.less | 34 + .../less/bordered-pulled.less | 25 + .../fonts/font-awesome-4.7.0/less/core.less | 12 + .../font-awesome-4.7.0/less/fixed-width.less | 6 + .../font-awesome-4.7.0/less/font-awesome.less | 18 + .../fonts/font-awesome-4.7.0/less/icons.less | 789 ++ .../fonts/font-awesome-4.7.0/less/larger.less | 13 + .../fonts/font-awesome-4.7.0/less/list.less | 19 + .../fonts/font-awesome-4.7.0/less/mixins.less | 60 + .../fonts/font-awesome-4.7.0/less/path.less | 15 + .../less/rotated-flipped.less | 20 + .../less/screen-reader.less | 5 + .../font-awesome-4.7.0/less/stacked.less | 20 + .../font-awesome-4.7.0/less/variables.less | 800 ++ .../font-awesome-4.7.0/scss/_animated.scss | 34 + .../scss/_bordered-pulled.scss | 25 + .../fonts/font-awesome-4.7.0/scss/_core.scss | 12 + .../font-awesome-4.7.0/scss/_fixed-width.scss | 6 + .../fonts/font-awesome-4.7.0/scss/_icons.scss | 789 ++ .../font-awesome-4.7.0/scss/_larger.scss | 13 + .../fonts/font-awesome-4.7.0/scss/_list.scss | 19 + .../font-awesome-4.7.0/scss/_mixins.scss | 60 + .../fonts/font-awesome-4.7.0/scss/_path.scss | 15 + .../scss/_rotated-flipped.scss | 20 + .../scss/_screen-reader.scss | 5 + .../font-awesome-4.7.0/scss/_stacked.scss | 20 + .../font-awesome-4.7.0/scss/_variables.scss | 800 ++ .../font-awesome-4.7.0/scss/font-awesome.scss | 18 + .../html/fonts/font-codemr/config.json | 24 + .../html/fonts/font-codemr/css/animation.css | 85 + .../fonts/font-codemr/css/codemr-codes.css | 2 + .../fonts/font-codemr/css/codemr-embedded.css | 55 + .../font-codemr/css/codemr-ie7-codes.css | 2 + .../html/fonts/font-codemr/css/codemr-ie7.css | 13 + .../html/fonts/font-codemr/css/codemr.css | 58 + .../html/fonts/font-codemr/demo.html | 309 + .../html/fonts/font-codemr/font/codemr.eot | Bin 0 -> 5016 bytes .../html/fonts/font-codemr/font/codemr.svg | 12 + .../html/fonts/font-codemr/font/codemr.ttf | Bin 0 -> 4856 bytes .../html/fonts/font-codemr/font/codemr.woff | Bin 0 -> 2740 bytes .../html/fonts/font-codemr/font/codemr.woff2 | Bin 0 -> 2212 bytes .../html/fonts/fontawesome-webfont.woff | Bin 0 -> 65452 bytes ...yrillic_latin-ext_greek-ext_greek-300.woff | Bin 0 -> 82320 bytes ...rillic_latin-ext_greek-ext_greek-300.woff2 | Bin 0 -> 63104 bytes ...yrillic_latin-ext_greek-ext_greek-700.woff | Bin 0 -> 82860 bytes ...rillic_latin-ext_greek-ext_greek-700.woff2 | Bin 0 -> 63396 bytes ...lic_latin-ext_greek-ext_greek-regular.woff | Bin 0 -> 82560 bytes ...ic_latin-ext_greek-ext_greek-regular.woff2 | Bin 0 -> 63156 bytes .../main_report/html/fonts/robotofonts.css | 28 + .../main_report/html/img/eqGraphlegend.png | Bin 0 -> 13748 bytes .../html/main_report/html/img/help.png | Bin 0 -> 239 bytes .../html/main_report/html/js/circlepack.js | 1 + .../html/main_report/html/js/d3.min.js | 1 + .../html/main_report/html/js/d3.tip.v0.6.3.js | 1 + .../main_report/html/js/dependency_wheel.js | 1 + .../html/main_report/html/js/donut3d.js | 1 + .../html/main_report/html/js/eq.js | 1 + .../main_report/html/js/metric_definitions.js | 1 + .../html/main_report/html/js/metricchart.js | 1 + .../html/main_report/html/js/sunburst.js | 1 + .../html/main_report/html/js/treemap.js | 1 + .../html/main_report/html/js/vis.js | 25 + .../main_report/html/js/vis_eq_cluster.js | 1 + .../main_report/html/js/vis_eq_graph_base.js | 1 + .../html/main_report/htmlx/Xdonut.html | 107 + .../html/main_report/htmlx/circlepack.html | 113 + .../html/main_report/htmlx/dependency.html | 31 + .../html/main_report/htmlx/donut.html | 179 + .../html/main_report/htmlx/donutcharts.html | 42 + .../main_report/htmlx/donutchartssimple.html | 26 + .../html/main_report/htmlx/lbd/README.md | 109 + .../html/main_report/htmlx/lbd/dashboard.html | 334 + .../html/main_report/htmlx/lbd/graphs.html | 263 + .../htmlx/lbd/metricdescriptions.html | 261 + .../main_report/htmlx/lbd/notifications.html | 310 + .../html/main_report/htmlx/lbd/table.html | 446 + .../html/main_report/htmlx/lbd/template.html | 154 + .../main_report/htmlx/metricchartmethod.html | 27 + .../main_report/htmlx/metricchartpackage.html | 25 + .../html/main_report/htmlx/metricchartx.html | 25 + .../htmlx/modeldata/defaultclassmetrics.js | 127 + .../htmlx/modeldata/overview_metric_data.js | 1 + .../htmlx/modeldata/packagedependency.js | 17 + .../htmlx/modeldata/summary_data.js | 6 + .../htmlx/modeldata/sunburst_data.js | 231 + .../main_report/htmlx/modeldata/table_data.js | 1 + .../html/main_report/htmlx/report.html | 28 + .../main_report/htmlx/reportforprint.html | 28 + .../html/main_report/htmlx/sunburst.html | 106 + .../html/main_report/htmlx/treemap.html | 56 + .../html/main_report/index.html | 1 + .../html/workingsets.js | 3 + .../serialx-core-utils-split.mdl | Bin 0 -> 48071 bytes .../serialx-core-utils-split.qa | 1 + .../serialx-core-utils-split.ws | 1 + .../html/graph_htmls/all_bymodularity.html | 2 +- .../html/graph_htmls/all_bymodularity.png | Bin 27506 -> 27509 bytes .../html/graph_htmls/all_bypackage.html | 2 +- .../html/graph_htmls/all_bypackage.png | Bin 2836 -> 34216 bytes .../html/graph_htmls/all_byprojectmodule.html | 2 +- .../html/graph_htmls/all_byprojectmodule.png | Bin 21825 -> 15761 bytes .../serialx-core/html/graph_htmls/all_nm.html | 2 +- .../serialx-core/html/graph_htmls/all_nm.png | Bin 24091 -> 24072 bytes .../graph_htmls/all_nm_inheritance 1.3.9.html | 2 +- .../graph_htmls/all_nm_inheritance 1.3.9.png | Bin 9958 -> 9547 bytes .../html/graph_htmls/all_nm_inheritance.html | 2 +- .../html/graph_htmls/all_nm_inheritance.png | Bin 9299 -> 9300 bytes .../html/graph_htmls/graphlist.js | 2 +- .../htmlx/modeldata/sunburst_data.js | 55 +- .../htmlx/modeldata/sunburst_data.js | 55 +- .../java/org/ugp/serialx/GenericScope.java | 6 +- .../src/main/java/org/ugp/serialx/Scope.java | 8 +- .../main/java/org/ugp/serialx/Serializer.java | 60 +- .../serialx/converters/BooleanConverter.java | 5 +- .../ugp/serialx/converters/NullConverter.java | 2 +- .../serialx/converters/NumberConverter.java | 2 +- .../serialx/converters/ProtocolConverter.java | 11 +- .../serialx/converters/StringConverter.java | 3 +- .../serialx/converters/VariableParser.java | 5 +- .../{Utils.java => MetaprogrammingUtils.java} | 439 +- .../java/org/ugp/serialx/utils/StrUtils.java | 424 + .../devtools/SerializationDebugger.java | 2 +- .../org/ugp/serialx/json/JsonSerializer.java | 3 +- .../json/converters/JsonObjectConverter.java | 4 +- .../org/ugp/serialx/juss/JussSerializer.java | 18 +- .../juss/converters/ArrayConverter.java | 7 +- .../juss/converters/ObjectConverter.java | 2 +- .../juss/converters/OperationGroups.java | 6 +- .../juss/converters/VariableConverter.java | 3 +- .../serialx/juss/protocols/AutoProtocol.java | 6 +- .../UniversalObjectInstantiationProtocol.java | 4 +- .../operators/ArithmeticOperators.java | 3 +- .../operators/ComparisonOperators.java | 2 +- .../ConditionalAssignmentOperators.java | 2 +- .../operators/LogicalOperators.java | 3 +- 249 files changed, 35143 insertions(+), 581 deletions(-) create mode 100644 SerialX-core/codemr/serialx-core-utils-split/graphs/all_bymodularity.cmr create mode 100644 SerialX-core/codemr/serialx-core-utils-split/graphs/all_bypackage.cmr create mode 100644 SerialX-core/codemr/serialx-core-utils-split/graphs/all_byprojectmodule.cmr create mode 100644 SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm.cmr create mode 100644 SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm_inheritance.cmr create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bypackage.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bypackage.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm_inheritance.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm_inheritance.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/graphlist.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/Xdonut.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/circlepack.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/dependency.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donut.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutcharts.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutchartssimple.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/README.md create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/dashboard.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/graphs.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/notifications.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/table.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/template.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartmethod.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartpackage.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartx.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/summary_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/table_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/report.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/reportforprint.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/sunburst.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/treemap.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/index.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/animate.min.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/bootstrap.min.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/demo.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/font-awesome.min.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/helptip.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/light-bootstrap-dashboard.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/pe-icon-7-stroke.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-icon-black-1.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-white-32.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/default-avatar.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/favicon.ico create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/loading-bubbles.svg create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/mask.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/new_logo.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/sidebar-5.jpg create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-notify.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-select.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap.min.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/chartist.min.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/demo.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/jquery-1.10.2.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/light-bootstrap-dashboard.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_alerts.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_buttons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_cards.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_chartist.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_checkbox-radio-switch.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_dropdown.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_footers.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_inputs.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_misc.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_mixins.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_navbars.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_responsive.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_sidebar-and-main-panel.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_tables.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_typography.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/_variables.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_buttons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_cards.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_chartist.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_icons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_inputs.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_labels.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_morphing-buttons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_navbars.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_social-buttons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_tabs.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_transparency.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/lbd/mixins/_vendor-prefixes.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/sass/light-bootstrap-dashboard.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/barchartstyle.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/graph.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/helptip.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/legend.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/style.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/treemap.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/css/vis.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/css/font-awesome.min.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/FontAwesome.otf create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.eot create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.svg create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/animated.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/bordered-pulled.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/core.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/fixed-width.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/font-awesome.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/icons.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/larger.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/list.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/mixins.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/path.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/rotated-flipped.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/screen-reader.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/stacked.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/less/variables.less create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_animated.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_bordered-pulled.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_core.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_fixed-width.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_icons.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_larger.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_list.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_mixins.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_path.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_rotated-flipped.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_screen-reader.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_stacked.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/_variables.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-awesome-4.7.0/scss/font-awesome.scss create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/config.json create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/animation.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/codemr-codes.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/codemr-embedded.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/codemr-ie7-codes.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/codemr-ie7.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/css/codemr.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/demo.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/font/codemr.eot create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/font/codemr.svg create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/font/codemr.ttf create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/font/codemr.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/font-codemr/font/codemr.woff2 create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/fontawesome-webfont.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-300.woff2 create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-700.woff2 create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/roboto-v15-cyrillic-ext_vietnamese_latin_cyrillic_latin-ext_greek-ext_greek-regular.woff2 create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/fonts/robotofonts.css create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/img/eqGraphlegend.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/img/help.png create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/circlepack.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/d3.min.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/d3.tip.v0.6.3.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/dependency_wheel.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/donut3d.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/eq.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/metric_definitions.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/metricchart.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/sunburst.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/treemap.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/vis.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/vis_eq_cluster.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/js/vis_eq_graph_base.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/Xdonut.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/circlepack.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/dependency.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donut.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donutcharts.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donutchartssimple.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/README.md create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/dashboard.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/graphs.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/metricdescriptions.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/notifications.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/table.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/template.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartmethod.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartpackage.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartx.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/defaultclassmetrics.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/overview_metric_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/packagedependency.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/summary_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/sunburst_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/table_data.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/report.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/reportforprint.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/sunburst.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/treemap.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/main_report/index.html create mode 100644 SerialX-core/codemr/serialx-core-utils-split/html/workingsets.js create mode 100644 SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.mdl create mode 100644 SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.qa create mode 100644 SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.ws rename SerialX-core/src/main/java/org/ugp/serialx/utils/{Utils.java => MetaprogrammingUtils.java} (55%) create mode 100644 SerialX-core/src/main/java/org/ugp/serialx/utils/StrUtils.java diff --git a/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bymodularity.cmr b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bymodularity.cmr new file mode 100644 index 0000000..4b6b6fe --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bymodularity.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":26},{"@type":"int","id":"#edges","v":67},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":50.0,"y":445.0},"B":{"x":277.0,"y":1269.0},"C":{"x":392.0,"y":554.0},"E":{"x":279.0,"y":637.0},"F":{"x":479.0,"y":227.0},"H":{"x":129.0,"y":1222.0},"I":{"x":86.0,"y":1245.0},"J":{"x":103.0,"y":464.0},"K":{"x":295.0,"y":656.0},"L":{"x":185.0,"y":1424.0},"M":{"x":311.0,"y":1126.0},"N":{"x":150.0,"y":620.0},"O":{"x":199.0,"y":314.0},"P":{"x":539.0,"y":549.0},"Q":{"x":157.0,"y":656.0},"R":{"x":262.0,"y":569.0},"k":{"x":65.0,"y":1143.0},"m":{"x":307.0,"y":692.0},"o":{"x":566.0,"y":142.0},"r":{"x":135.0,"y":503.0},"s":{"x":370.0,"y":1352.0},"t":{"x":110.0,"y":364.0},"v":{"x":262.0,"y":536.0},"w":{"x":678.0,"y":50.0},"y":{"x":222.0,"y":419.0},"z":{"x":230.0,"y":527.0}},"vList":[{"type":"w"},{"type":"z"},{"type":"v"},{"type":"B"},{"type":"J"},{"type":"I"},{"type":"K"},{"type":"H"},{"type":"M"},{"type":"o"},{"type":"r"},{"type":"C"},{"type":"L"},{"type":"N"},{"type":"O"},{"type":"F"},{"type":"R"},{"type":"k"},{"type":"P"},{"type":"E"},{"type":"y"},{"type":"t"},{"type":"m"},{"type":"Q"},{"type":"A"},{"type":"s"}],"eList":[{"L":[{"s":"K","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"C","k":6,"w":2},{"s":"I","d":"C","k":55,"w":5},{"s":"I","d":"C","k":53,"w":1},{"s":"I","d":"C","k":51,"w":4},{"s":"I","d":"C","k":7,"w":1}]},{"L":[{"s":"w","d":"t","k":55,"w":4},{"s":"w","d":"t","k":51,"w":2}]},{"L":[{"s":"M","d":"C","k":55,"w":4},{"s":"M","d":"C","k":53,"w":1},{"s":"M","d":"C","k":51,"w":1},{"s":"M","d":"C","k":7,"w":1}]},{"L":[{"s":"Q","d":"C","k":3,"w":1},{"s":"Q","d":"C","k":51,"w":3}]},{"L":[{"s":"w","d":"H","k":55,"w":5}]},{"L":[{"s":"w","d":"C","k":55,"w":4},{"s":"w","d":"C","k":51,"w":6}]},{"L":[{"s":"M","d":"s","k":53,"w":1}]},{"L":[{"s":"z","d":"Q","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"R","d":"N","k":55,"w":2}]},{"L":[{"s":"w","d":"N","k":55,"w":2}]},{"L":[{"s":"t","d":"P","k":2,"w":1},{"s":"t","d":"P","k":55,"w":2}]},{"L":[{"s":"I","d":"P","k":51,"w":3}]},{"L":[{"s":"O","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"t","k":55,"w":2},{"s":"L","d":"t","k":51,"w":2}]},{"L":[{"s":"v","d":"N","k":55,"w":1}]},{"L":[{"s":"I","d":"M","k":55,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"I","d":"t","k":6,"w":1},{"s":"I","d":"t","k":55,"w":2},{"s":"I","d":"t","k":51,"w":5}]},{"L":[{"s":"B","d":"M","k":55,"w":1}]},{"L":[{"s":"r","d":"L","k":55,"w":2}]},{"L":[{"s":"M","d":"H","k":55,"w":2}]},{"L":[{"s":"L","d":"H","k":55,"w":1}]},{"L":[{"s":"K","d":"N","k":55,"w":2}]},{"L":[{"s":"F","d":"o","k":6,"w":1},{"s":"F","d":"o","k":51,"w":4}]},{"L":[{"s":"o","d":"F","k":51,"w":2},{"s":"o","d":"F","k":7,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"z","d":"C","k":51,"w":3}]},{"L":[{"s":"m","d":"C","k":51,"w":3}]},{"L":[{"s":"v","d":"Q","k":3,"w":1}]},{"L":[{"s":"B","d":"L","k":55,"w":4},{"s":"B","d":"L","k":51,"w":1}]},{"L":[{"s":"C","d":"P","k":2,"w":1}]},{"L":[{"s":"s","d":"N","k":55,"w":2}]},{"L":[{"s":"I","d":"m","k":55,"w":1}]},{"L":[{"s":"v","d":"C","k":51,"w":3}]},{"L":[{"s":"B","d":"I","k":55,"w":1}]},{"L":[{"s":"I","d":"k","k":3,"w":1},{"s":"I","d":"k","k":55,"w":3}]},{"L":[{"s":"R","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"s","k":2,"w":1},{"s":"I","d":"s","k":55,"w":12},{"s":"I","d":"s","k":53,"w":1},{"s":"I","d":"s","k":51,"w":4},{"s":"I","d":"s","k":58,"w":3},{"s":"I","d":"s","k":7,"w":1}]},{"L":[{"s":"y","d":"L","k":55,"w":4},{"s":"y","d":"L","k":51,"w":2},{"s":"y","d":"L","k":7,"w":1}]},{"L":[{"s":"w","d":"s","k":7,"w":1}]},{"L":[{"s":"s","d":"H","k":55,"w":1}]},{"L":[{"s":"r","d":"H","k":55,"w":1}]},{"L":[{"s":"I","d":"L","k":55,"w":7},{"s":"I","d":"L","k":51,"w":6},{"s":"I","d":"L","k":58,"w":4}]},{"L":[{"s":"y","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"M","k":55,"w":2}]},{"L":[{"s":"m","d":"Q","k":3,"w":1}]},{"L":[{"s":"z","d":"H","k":55,"w":2}]},{"L":[{"s":"C","d":"Q","k":3,"w":1},{"s":"C","d":"Q","k":6,"w":1},{"s":"C","d":"Q","k":51,"w":3}]},{"L":[{"s":"R","d":"C","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":3},{"s":"M","d":"I","k":51,"w":1}]},{"L":[{"s":"B","d":"C","k":3,"w":1},{"s":"B","d":"C","k":51,"w":2}]},{"L":[{"s":"L","d":"M","k":55,"w":4}]},{"L":[{"s":"B","d":"s","k":53,"w":1}]},{"L":[{"s":"s","d":"L","k":2,"w":1},{"s":"s","d":"L","k":55,"w":47},{"s":"s","d":"L","k":51,"w":6},{"s":"s","d":"L","k":58,"w":1},{"s":"s","d":"L","k":7,"w":1}]},{"L":[{"s":"E","d":"Q","k":3,"w":1}]},{"L":[{"s":"E","d":"C","k":51,"w":3}]},{"L":[{"s":"K","d":"C","k":51,"w":3}]},{"L":[{"s":"w","d":"Q","k":3,"w":1}]},{"L":[{"s":"t","d":"H","k":55,"w":3}]},{"L":[{"s":"J","d":"t","k":2,"w":1}]},{"L":[{"s":"m","d":"N","k":55,"w":4}]},{"L":[{"s":"B","d":"N","k":55,"w":2}]},{"L":[{"s":"w","d":"o","k":55,"w":2}]},{"L":[{"s":"s","d":"M","k":55,"w":2}]},{"L":[{"s":"I","d":"N","k":55,"w":3}]}],"clusterMap":{"A":3,"B":2,"C":1,"E":1,"F":4,"H":2,"I":2,"J":3,"K":1,"L":2,"M":2,"N":1,"O":3,"P":1,"Q":1,"R":1,"k":2,"m":1,"o":4,"r":3,"s":2,"t":3,"v":1,"w":4,"y":3,"z":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bypackage.cmr b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bypackage.cmr new file mode 100644 index 0000000..efda66b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_bypackage.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":26},{"@type":"int","id":"#edges","v":67},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":5},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":750.0,"y":295.0},"B":{"x":762.0,"y":497.0},"C":{"x":651.0,"y":327.0},"E":{"x":549.0,"y":404.0},"F":{"x":874.0,"y":79.0},"H":{"x":258.0,"y":947.0},"I":{"x":1015.0,"y":1171.0},"J":{"x":778.0,"y":223.0},"K":{"x":579.0,"y":444.0},"L":{"x":1200.0,"y":1321.0},"M":{"x":50.0,"y":880.0},"N":{"x":133.0,"y":1105.0},"O":{"x":929.0,"y":230.0},"P":{"x":275.0,"y":1085.0},"Q":{"x":449.0,"y":471.0},"R":{"x":523.0,"y":368.0},"k":{"x":988.0,"y":1275.0},"m":{"x":598.0,"y":499.0},"o":{"x":992.0,"y":50.0},"r":{"x":755.0,"y":396.0},"s":{"x":968.0,"y":1390.0},"t":{"x":852.0,"y":295.0},"v":{"x":626.0,"y":469.0},"w":{"x":437.0,"y":246.0},"y":{"x":874.0,"y":415.0},"z":{"x":495.0,"y":318.0}},"vList":[{"type":"w"},{"type":"z"},{"type":"v"},{"type":"B"},{"type":"J"},{"type":"I"},{"type":"K"},{"type":"H"},{"type":"M"},{"type":"o"},{"type":"r"},{"type":"C"},{"type":"L"},{"type":"N"},{"type":"O"},{"type":"F"},{"type":"R"},{"type":"k"},{"type":"P"},{"type":"E"},{"type":"y"},{"type":"t"},{"type":"m"},{"type":"Q"},{"type":"A"},{"type":"s"}],"eList":[{"L":[{"s":"B","d":"L","k":55,"w":4},{"s":"B","d":"L","k":51,"w":1}]},{"L":[{"s":"w","d":"M","k":55,"w":2}]},{"L":[{"s":"I","d":"s","k":2,"w":1},{"s":"I","d":"s","k":55,"w":12},{"s":"I","d":"s","k":53,"w":1},{"s":"I","d":"s","k":51,"w":4},{"s":"I","d":"s","k":58,"w":3},{"s":"I","d":"s","k":7,"w":1}]},{"L":[{"s":"R","d":"N","k":55,"w":2}]},{"L":[{"s":"s","d":"M","k":55,"w":2}]},{"L":[{"s":"z","d":"Q","k":3,"w":1}]},{"L":[{"s":"m","d":"C","k":51,"w":3}]},{"L":[{"s":"y","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"N","k":55,"w":2}]},{"L":[{"s":"m","d":"N","k":55,"w":4}]},{"L":[{"s":"w","d":"N","k":55,"w":2}]},{"L":[{"s":"E","d":"C","k":51,"w":3}]},{"L":[{"s":"C","d":"Q","k":3,"w":1},{"s":"C","d":"Q","k":6,"w":1},{"s":"C","d":"Q","k":51,"w":3}]},{"L":[{"s":"E","d":"Q","k":3,"w":1}]},{"L":[{"s":"z","d":"C","k":51,"w":3}]},{"L":[{"s":"I","d":"P","k":51,"w":3}]},{"L":[{"s":"v","d":"Q","k":3,"w":1}]},{"L":[{"s":"v","d":"N","k":55,"w":1}]},{"L":[{"s":"w","d":"o","k":55,"w":2}]},{"L":[{"s":"Q","d":"C","k":3,"w":1},{"s":"Q","d":"C","k":51,"w":3}]},{"L":[{"s":"M","d":"H","k":55,"w":2}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"w","d":"t","k":55,"w":4},{"s":"w","d":"t","k":51,"w":2}]},{"L":[{"s":"I","d":"N","k":55,"w":3}]},{"L":[{"s":"M","d":"s","k":53,"w":1}]},{"L":[{"s":"o","d":"F","k":51,"w":2},{"s":"o","d":"F","k":7,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":1}]},{"L":[{"s":"K","d":"N","k":55,"w":2}]},{"L":[{"s":"t","d":"H","k":55,"w":3}]},{"L":[{"s":"J","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"H","k":55,"w":1}]},{"L":[{"s":"L","d":"M","k":55,"w":4}]},{"L":[{"s":"O","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"H","k":55,"w":1}]},{"L":[{"s":"F","d":"o","k":6,"w":1},{"s":"F","d":"o","k":51,"w":4}]},{"L":[{"s":"B","d":"C","k":3,"w":1},{"s":"B","d":"C","k":51,"w":2}]},{"L":[{"s":"I","d":"M","k":55,"w":4}]},{"L":[{"s":"v","d":"C","k":51,"w":3}]},{"L":[{"s":"I","d":"C","k":6,"w":2},{"s":"I","d":"C","k":55,"w":5},{"s":"I","d":"C","k":53,"w":1},{"s":"I","d":"C","k":51,"w":4},{"s":"I","d":"C","k":7,"w":1}]},{"L":[{"s":"I","d":"m","k":55,"w":1}]},{"L":[{"s":"C","d":"P","k":2,"w":1}]},{"L":[{"s":"M","d":"I","k":55,"w":3},{"s":"M","d":"I","k":51,"w":1}]},{"L":[{"s":"w","d":"H","k":55,"w":5}]},{"L":[{"s":"s","d":"L","k":2,"w":1},{"s":"s","d":"L","k":55,"w":47},{"s":"s","d":"L","k":51,"w":6},{"s":"s","d":"L","k":58,"w":1},{"s":"s","d":"L","k":7,"w":1}]},{"L":[{"s":"B","d":"M","k":55,"w":1}]},{"L":[{"s":"K","d":"Q","k":3,"w":1}]},{"L":[{"s":"y","d":"L","k":55,"w":4},{"s":"y","d":"L","k":51,"w":2},{"s":"y","d":"L","k":7,"w":1}]},{"L":[{"s":"R","d":"C","k":51,"w":3}]},{"L":[{"s":"L","d":"t","k":55,"w":2},{"s":"L","d":"t","k":51,"w":2}]},{"L":[{"s":"B","d":"N","k":55,"w":2}]},{"L":[{"s":"I","d":"t","k":6,"w":1},{"s":"I","d":"t","k":55,"w":2},{"s":"I","d":"t","k":51,"w":5}]},{"L":[{"s":"K","d":"C","k":51,"w":3}]},{"L":[{"s":"R","d":"Q","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"M","d":"C","k":55,"w":4},{"s":"M","d":"C","k":53,"w":1},{"s":"M","d":"C","k":51,"w":1},{"s":"M","d":"C","k":7,"w":1}]},{"L":[{"s":"m","d":"Q","k":3,"w":1}]},{"L":[{"s":"w","d":"C","k":55,"w":4},{"s":"w","d":"C","k":51,"w":6}]},{"L":[{"s":"w","d":"s","k":7,"w":1}]},{"L":[{"s":"L","d":"H","k":55,"w":1}]},{"L":[{"s":"z","d":"H","k":55,"w":2}]},{"L":[{"s":"r","d":"L","k":55,"w":2}]},{"L":[{"s":"B","d":"s","k":53,"w":1}]},{"L":[{"s":"I","d":"k","k":3,"w":1},{"s":"I","d":"k","k":55,"w":3}]},{"L":[{"s":"w","d":"Q","k":3,"w":1}]},{"L":[{"s":"t","d":"P","k":2,"w":1},{"s":"t","d":"P","k":55,"w":2}]},{"L":[{"s":"I","d":"L","k":55,"w":7},{"s":"I","d":"L","k":51,"w":6},{"s":"I","d":"L","k":58,"w":4}]}],"clusterMap":{"A":2,"B":1,"C":1,"E":1,"F":5,"H":3,"I":4,"J":2,"K":1,"L":4,"M":3,"N":3,"O":2,"P":3,"Q":1,"R":1,"k":4,"m":1,"o":5,"r":2,"s":4,"t":2,"v":1,"w":1,"y":2,"z":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/graphs/all_byprojectmodule.cmr b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_byprojectmodule.cmr new file mode 100644 index 0000000..5a30acd --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_byprojectmodule.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":26},{"@type":"int","id":"#edges","v":67},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":true},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":6},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":213.0,"y":276.0},"B":{"x":199.0,"y":505.0},"C":{"x":317.0,"y":352.0},"E":{"x":185.0,"y":280.0},"F":{"x":387.0,"y":50.0},"H":{"x":226.0,"y":500.0},"I":{"x":250.0,"y":614.0},"J":{"x":119.0,"y":238.0},"K":{"x":183.0,"y":312.0},"L":{"x":50.0,"y":586.0},"M":{"x":80.0,"y":372.0},"N":{"x":63.0,"y":406.0},"O":{"x":89.0,"y":264.0},"P":{"x":249.0,"y":464.0},"Q":{"x":55.0,"y":339.0},"R":{"x":183.0,"y":370.0},"k":{"x":330.0,"y":679.0},"m":{"x":196.0,"y":453.0},"o":{"x":267.0,"y":64.0},"r":{"x":76.0,"y":468.0},"s":{"x":333.0,"y":401.0},"t":{"x":118.0,"y":351.0},"v":{"x":204.0,"y":389.0},"w":{"x":217.0,"y":204.0},"y":{"x":164.0,"y":476.0},"z":{"x":182.0,"y":342.0}},"vList":[{"type":"w"},{"type":"z"},{"type":"v"},{"type":"B"},{"type":"J"},{"type":"I"},{"type":"K"},{"type":"H"},{"type":"M"},{"type":"o"},{"type":"r"},{"type":"C"},{"type":"L"},{"type":"N"},{"type":"O"},{"type":"F"},{"type":"R"},{"type":"k"},{"type":"P"},{"type":"E"},{"type":"y"},{"type":"t"},{"type":"m"},{"type":"Q"},{"type":"A"},{"type":"s"}],"eList":[{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"t","k":55,"w":2},{"s":"L","d":"t","k":51,"w":2}]},{"L":[{"s":"t","d":"H","k":55,"w":3}]},{"L":[{"s":"w","d":"o","k":55,"w":2}]},{"L":[{"s":"m","d":"Q","k":3,"w":1}]},{"L":[{"s":"w","d":"H","k":55,"w":5}]},{"L":[{"s":"v","d":"Q","k":3,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":1}]},{"L":[{"s":"I","d":"N","k":55,"w":3}]},{"L":[{"s":"I","d":"s","k":2,"w":1},{"s":"I","d":"s","k":55,"w":12},{"s":"I","d":"s","k":53,"w":1},{"s":"I","d":"s","k":51,"w":4},{"s":"I","d":"s","k":58,"w":3},{"s":"I","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"Q","k":3,"w":1}]},{"L":[{"s":"E","d":"Q","k":3,"w":1}]},{"L":[{"s":"M","d":"C","k":55,"w":4},{"s":"M","d":"C","k":53,"w":1},{"s":"M","d":"C","k":51,"w":1},{"s":"M","d":"C","k":7,"w":1}]},{"L":[{"s":"s","d":"N","k":55,"w":2}]},{"L":[{"s":"I","d":"m","k":55,"w":1}]},{"L":[{"s":"t","d":"P","k":2,"w":1},{"s":"t","d":"P","k":55,"w":2}]},{"L":[{"s":"L","d":"H","k":55,"w":1}]},{"L":[{"s":"z","d":"Q","k":3,"w":1}]},{"L":[{"s":"o","d":"F","k":51,"w":2},{"s":"o","d":"F","k":7,"w":1}]},{"L":[{"s":"B","d":"N","k":55,"w":2}]},{"L":[{"s":"w","d":"t","k":55,"w":4},{"s":"w","d":"t","k":51,"w":2}]},{"L":[{"s":"s","d":"H","k":55,"w":1}]},{"L":[{"s":"w","d":"C","k":55,"w":4},{"s":"w","d":"C","k":51,"w":6}]},{"L":[{"s":"M","d":"s","k":53,"w":1}]},{"L":[{"s":"O","d":"t","k":2,"w":1}]},{"L":[{"s":"B","d":"L","k":55,"w":4},{"s":"B","d":"L","k":51,"w":1}]},{"L":[{"s":"M","d":"H","k":55,"w":2}]},{"L":[{"s":"s","d":"L","k":2,"w":1},{"s":"s","d":"L","k":55,"w":47},{"s":"s","d":"L","k":51,"w":6},{"s":"s","d":"L","k":58,"w":1},{"s":"s","d":"L","k":7,"w":1}]},{"L":[{"s":"s","d":"M","k":55,"w":2}]},{"L":[{"s":"R","d":"C","k":51,"w":3}]},{"L":[{"s":"K","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"C","k":6,"w":2},{"s":"I","d":"C","k":55,"w":5},{"s":"I","d":"C","k":53,"w":1},{"s":"I","d":"C","k":51,"w":4},{"s":"I","d":"C","k":7,"w":1}]},{"L":[{"s":"I","d":"P","k":51,"w":3}]},{"L":[{"s":"Q","d":"C","k":3,"w":1},{"s":"Q","d":"C","k":51,"w":3}]},{"L":[{"s":"r","d":"H","k":55,"w":1}]},{"L":[{"s":"R","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"M","k":55,"w":4}]},{"L":[{"s":"C","d":"Q","k":3,"w":1},{"s":"C","d":"Q","k":6,"w":1},{"s":"C","d":"Q","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":3},{"s":"M","d":"I","k":51,"w":1}]},{"L":[{"s":"I","d":"t","k":6,"w":1},{"s":"I","d":"t","k":55,"w":2},{"s":"I","d":"t","k":51,"w":5}]},{"L":[{"s":"w","d":"M","k":55,"w":2}]},{"L":[{"s":"B","d":"M","k":55,"w":1}]},{"L":[{"s":"w","d":"N","k":55,"w":2}]},{"L":[{"s":"m","d":"N","k":55,"w":4}]},{"L":[{"s":"z","d":"H","k":55,"w":2}]},{"L":[{"s":"F","d":"o","k":6,"w":1},{"s":"F","d":"o","k":51,"w":4}]},{"L":[{"s":"E","d":"C","k":51,"w":3}]},{"L":[{"s":"I","d":"L","k":55,"w":7},{"s":"I","d":"L","k":51,"w":6},{"s":"I","d":"L","k":58,"w":4}]},{"L":[{"s":"K","d":"N","k":55,"w":2}]},{"L":[{"s":"v","d":"C","k":51,"w":3}]},{"L":[{"s":"w","d":"s","k":7,"w":1}]},{"L":[{"s":"K","d":"C","k":51,"w":3}]},{"L":[{"s":"R","d":"N","k":55,"w":2}]},{"L":[{"s":"y","d":"t","k":2,"w":1}]},{"L":[{"s":"I","d":"k","k":3,"w":1},{"s":"I","d":"k","k":55,"w":3}]},{"L":[{"s":"z","d":"C","k":51,"w":3}]},{"L":[{"s":"m","d":"C","k":51,"w":3}]},{"L":[{"s":"J","d":"t","k":2,"w":1}]},{"L":[{"s":"y","d":"L","k":55,"w":4},{"s":"y","d":"L","k":51,"w":2},{"s":"y","d":"L","k":7,"w":1}]},{"L":[{"s":"C","d":"P","k":2,"w":1}]},{"L":[{"s":"B","d":"C","k":3,"w":1},{"s":"B","d":"C","k":51,"w":2}]},{"L":[{"s":"v","d":"N","k":55,"w":1}]},{"L":[{"s":"B","d":"s","k":53,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"r","d":"L","k":55,"w":2}]},{"L":[{"s":"L","d":"M","k":55,"w":4}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]}],"clusterMap":{"A":1,"B":1,"C":1,"E":1,"F":1,"H":1,"I":1,"J":1,"K":1,"L":1,"M":1,"N":1,"O":1,"P":1,"Q":1,"R":1,"k":1,"m":1,"o":1,"r":1,"s":1,"t":1,"v":1,"w":1,"y":1,"z":1}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm.cmr b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm.cmr new file mode 100644 index 0000000..854f8a6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":26},{"@type":"int","id":"#edges","v":67},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":0},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":479.0,"y":350.0},"B":{"x":527.0,"y":668.0},"C":{"x":655.0,"y":411.0},"E":{"x":476.0,"y":558.0},"F":{"x":526.0,"y":252.0},"H":{"x":148.0,"y":292.0},"I":{"x":474.0,"y":855.0},"J":{"x":306.0,"y":287.0},"K":{"x":487.0,"y":589.0},"L":{"x":177.0,"y":727.0},"M":{"x":279.0,"y":509.0},"N":{"x":242.0,"y":526.0},"O":{"x":426.0,"y":313.0},"P":{"x":569.0,"y":632.0},"Q":{"x":265.0,"y":470.0},"R":{"x":482.0,"y":610.0},"k":{"x":298.0,"y":724.0},"m":{"x":513.0,"y":606.0},"o":{"x":654.0,"y":50.0},"r":{"x":50.0,"y":517.0},"s":{"x":569.0,"y":417.0},"t":{"x":325.0,"y":507.0},"v":{"x":475.0,"y":635.0},"w":{"x":431.0,"y":189.0},"y":{"x":416.0,"y":731.0},"z":{"x":421.0,"y":270.0}},"vList":[{"type":"w"},{"type":"z"},{"type":"v"},{"type":"B"},{"type":"J"},{"type":"I"},{"type":"K"},{"type":"H"},{"type":"M"},{"type":"o"},{"type":"r"},{"type":"C"},{"type":"L"},{"type":"N"},{"type":"O"},{"type":"F"},{"type":"R"},{"type":"k"},{"type":"P"},{"type":"E"},{"type":"y"},{"type":"t"},{"type":"m"},{"type":"Q"},{"type":"A"},{"type":"s"}],"eList":[{"L":[{"s":"B","d":"M","k":55,"w":1}]},{"L":[{"s":"o","d":"F","k":51,"w":2},{"s":"o","d":"F","k":7,"w":1}]},{"L":[{"s":"w","d":"o","k":55,"w":2}]},{"L":[{"s":"I","d":"m","k":55,"w":1}]},{"L":[{"s":"w","d":"t","k":55,"w":4},{"s":"w","d":"t","k":51,"w":2}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"N","k":55,"w":2}]},{"L":[{"s":"y","d":"L","k":55,"w":4},{"s":"y","d":"L","k":51,"w":2},{"s":"y","d":"L","k":7,"w":1}]},{"L":[{"s":"y","d":"t","k":2,"w":1}]},{"L":[{"s":"z","d":"H","k":55,"w":2}]},{"L":[{"s":"m","d":"Q","k":3,"w":1}]},{"L":[{"s":"R","d":"Q","k":3,"w":1}]},{"L":[{"s":"w","d":"Q","k":3,"w":1}]},{"L":[{"s":"R","d":"N","k":55,"w":2}]},{"L":[{"s":"E","d":"C","k":51,"w":3}]},{"L":[{"s":"m","d":"C","k":51,"w":3}]},{"L":[{"s":"I","d":"C","k":6,"w":2},{"s":"I","d":"C","k":55,"w":5},{"s":"I","d":"C","k":53,"w":1},{"s":"I","d":"C","k":51,"w":4},{"s":"I","d":"C","k":7,"w":1}]},{"L":[{"s":"v","d":"Q","k":3,"w":1}]},{"L":[{"s":"z","d":"C","k":51,"w":3}]},{"L":[{"s":"s","d":"t","k":51,"w":2}]},{"L":[{"s":"I","d":"P","k":51,"w":3}]},{"L":[{"s":"I","d":"s","k":2,"w":1},{"s":"I","d":"s","k":55,"w":12},{"s":"I","d":"s","k":53,"w":1},{"s":"I","d":"s","k":51,"w":4},{"s":"I","d":"s","k":58,"w":3},{"s":"I","d":"s","k":7,"w":1}]},{"L":[{"s":"C","d":"Q","k":3,"w":1},{"s":"C","d":"Q","k":6,"w":1},{"s":"C","d":"Q","k":51,"w":3}]},{"L":[{"s":"t","d":"H","k":55,"w":3}]},{"L":[{"s":"M","d":"H","k":55,"w":2}]},{"L":[{"s":"r","d":"L","k":55,"w":2}]},{"L":[{"s":"B","d":"N","k":55,"w":2}]},{"L":[{"s":"K","d":"N","k":55,"w":2}]},{"L":[{"s":"B","d":"L","k":55,"w":4},{"s":"B","d":"L","k":51,"w":1}]},{"L":[{"s":"m","d":"N","k":55,"w":4}]},{"L":[{"s":"L","d":"H","k":55,"w":1}]},{"L":[{"s":"E","d":"Q","k":3,"w":1}]},{"L":[{"s":"v","d":"N","k":55,"w":1}]},{"L":[{"s":"I","d":"L","k":55,"w":7},{"s":"I","d":"L","k":51,"w":6},{"s":"I","d":"L","k":58,"w":4}]},{"L":[{"s":"R","d":"C","k":51,"w":3}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"L","d":"M","k":55,"w":4}]},{"L":[{"s":"t","d":"P","k":2,"w":1},{"s":"t","d":"P","k":55,"w":2}]},{"L":[{"s":"r","d":"H","k":55,"w":1}]},{"L":[{"s":"I","d":"M","k":55,"w":4}]},{"L":[{"s":"s","d":"H","k":55,"w":1}]},{"L":[{"s":"s","d":"L","k":2,"w":1},{"s":"s","d":"L","k":55,"w":47},{"s":"s","d":"L","k":51,"w":6},{"s":"s","d":"L","k":58,"w":1},{"s":"s","d":"L","k":7,"w":1}]},{"L":[{"s":"I","d":"k","k":3,"w":1},{"s":"I","d":"k","k":55,"w":3}]},{"L":[{"s":"C","d":"P","k":2,"w":1}]},{"L":[{"s":"v","d":"C","k":51,"w":3}]},{"L":[{"s":"M","d":"I","k":55,"w":3},{"s":"M","d":"I","k":51,"w":1}]},{"L":[{"s":"Q","d":"C","k":3,"w":1},{"s":"Q","d":"C","k":51,"w":3}]},{"L":[{"s":"M","d":"s","k":53,"w":1}]},{"L":[{"s":"K","d":"Q","k":3,"w":1}]},{"L":[{"s":"B","d":"I","k":55,"w":1}]},{"L":[{"s":"K","d":"C","k":51,"w":3}]},{"L":[{"s":"J","d":"t","k":2,"w":1}]},{"L":[{"s":"z","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"N","k":55,"w":3}]},{"L":[{"s":"w","d":"N","k":55,"w":2}]},{"L":[{"s":"w","d":"C","k":55,"w":4},{"s":"w","d":"C","k":51,"w":6}]},{"L":[{"s":"B","d":"s","k":53,"w":1}]},{"L":[{"s":"L","d":"t","k":55,"w":2},{"s":"L","d":"t","k":51,"w":2}]},{"L":[{"s":"M","d":"C","k":55,"w":4},{"s":"M","d":"C","k":53,"w":1},{"s":"M","d":"C","k":51,"w":1},{"s":"M","d":"C","k":7,"w":1}]},{"L":[{"s":"F","d":"o","k":6,"w":1},{"s":"F","d":"o","k":51,"w":4}]},{"L":[{"s":"O","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"M","k":55,"w":2}]},{"L":[{"s":"w","d":"s","k":7,"w":1}]},{"L":[{"s":"w","d":"H","k":55,"w":5}]},{"L":[{"s":"B","d":"C","k":3,"w":1},{"s":"B","d":"C","k":51,"w":2}]},{"L":[{"s":"w","d":"M","k":55,"w":2}]},{"L":[{"s":"I","d":"t","k":6,"w":1},{"s":"I","d":"t","k":55,"w":2},{"s":"I","d":"t","k":51,"w":5}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm_inheritance.cmr b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm_inheritance.cmr new file mode 100644 index 0000000..eb948d3 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/graphs/all_nm_inheritance.cmr @@ -0,0 +1 @@ +{"properties":{"elementList":[{"list":[{"@type":"prop","id":"Edge Thickness","v":"1"},{"@type":"bool","id":"Show Edge Label","v":false},{"@type":"bool","id":"Show Directed Edges","v":true},{"@type":"bool","id":"Show Module Color in Vertex","v":false},{"@type":"bool","id":"Vertex Shape by Module","v":false},{"@type":"prop","id":"Vertex Size","v":"20"},{"@type":"bool","id":"Show Vertex Name","v":true},{"@type":"prop","id":"Font Size","v":"10"},{"@type":"bool","id":"Show Name of Highlighted Vertices","v":true},{"@type":"bool","id":"Show Name of Problematic Vertices","v":true},{"@type":"bool","id":"Show Vertex Label","v":false},{"@type":"bool","id":"Filter by Degree","v":false},{"@type":"prop","id":"Vertex Min Degree Filter","v":"0"},{"@type":"prop","id":"Vertex Max Degree Filter","v":"20"},{"@type":"bool","id":"Show problematics and their fan-ins","v":false},{"@type":"bool","id":"Show problematics and their fan-outs","v":false},{"@type":"int","id":"#vertices","v":21},{"@type":"int","id":"#edges","v":20},{"@type":"prop","id":"Notes","v":""},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Layout","v":1},{"@type":"bool","id":"Group Modules","v":false},{"@type":"bool","id":"Add Synthetic Edges","v":true},{"@type":"double","id":"Leaf Connection Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Coefficient","v":0.0},{"@type":"double","id":"Inter-Module Coefficient","v":0.0},{"@type":"double","id":"Intra-Module Distance ","v":20.0},{"@type":"double","id":"Inter-Module Distance ","v":200.0},{"@type":"double","id":"Default Distance ","v":50.0},{"@type":"double","id":"Circle Radius","v":405.0},{"@type":"double","id":"Horizontal Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Horizontal Tree Depth Spacing","v":100.0},{"@type":"double","id":"Horizontal Subtree Spacing","v":100.0},{"@type":"double","id":"Vertical Tree Breadth Spacing","v":20.0},{"@type":"double","id":"Vertical Tree Depth Spacing","v":100.0},{"@type":"double","id":"Vertical Subtree Spacing","v":100.0},{"@type":"double","id":"Radial Radius Increment","v":100.0},{"@type":"bool","id":"Radial Auto-scale","v":false},{"@type":"double","id":"Radial Bound Start Angle(in radian)","v":0.0},{"@type":"double","id":"Radial Bound Width(in radian)","v":6.283185307179586},{"@type":"int","id":"Modularization Algorithm","v":2},{"@type":"int","id":"Aggregation Strategy","v":0},{"@type":"prop","id":"Authoritative File","v":""},{"@type":"prop","id":"Weighting Strategy","v":"1"},{"@type":"bool","id":"Detailed Modularization Analysis","v":false},{"@type":"bool","id":"Exclude Ignored Classes From Analysis Only","v":false},{"@type":"bool","id":"Ignore Library Classes","v":false},{"@type":"bool","id":"Ignore Omni-client Classes","v":false},{"@type":"bool","id":"Ignore Omni-supplier Classes","v":false},{"@type":"bool","id":"Ignore Omni-Central Classes","v":false},{"@type":"bool","id":"Use Weighted Graph","v":false}]}]},"relations":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":1},{"@type":"int","id":"trgtKd","v":1},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-26624}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"hndldKd","v":2},{"@type":"int","id":"trgtKd","v":2},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-14312668}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":3},{"@type":"int","id":"trgtKd","v":3},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":4},{"@type":"int","id":"trgtKd","v":4},{"@type":"prop","id":"w","v":"2"},{"@type":"rgb","id":"clr","v":-11110404}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":24},{"@type":"int","id":"trgtKd","v":24},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":26},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":22},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":27},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":5},{"@type":"int","id":"trgtKd","v":5},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":6},{"@type":"int","id":"trgtKd","v":6},{"@type":"prop","id":"w","v":"0"},{"@type":"rgb","id":"clr","v":-6543440}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":8},{"@type":"int","id":"trgtKd","v":8},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-7114533}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":17},{"@type":"int","id":"trgtKd","v":17},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":18},{"@type":"int","id":"trgtKd","v":18},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":19},{"@type":"int","id":"trgtKd","v":19},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":20},{"@type":"int","id":"trgtKd","v":20},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-16728876}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":14},{"@type":"int","id":"trgtKd","v":14},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-4804686}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":7},{"@type":"int","id":"trgtKd","v":7},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-5317}]},{"list":[{"@type":"bool","id":"enabled","v":false},{"@type":"int","id":"hndldKd","v":16},{"@type":"int","id":"trgtKd","v":16},{"@type":"prop","id":"w","v":"1"},{"@type":"rgb","id":"clr","v":-1762269}]}]},"labelQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"InDegree>0 AND OutDegree=0"},{"@type":"prop","id":"NAME","v":"library"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))AND NOT (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-client"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":"(InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable)) AND NOT (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-supplier"},{"@type":"prop","id":"VALUE","v":"true"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"prop","id":"CONDITION","v":" (OutDegree> 3 * (SELECT AVG(OutDegree) FROM metricTable)) AND (InDegree> 3 * (SELECT AVG(InDegree) FROM metricTable))"},{"@type":"prop","id":"NAME","v":"omni-central"},{"@type":"prop","id":"VALUE","v":"true"}]}]},"dbQuery":{"elementList":[{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO <= 5)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 5 AND CBO <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 10 AND CBO <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 20 AND CBO <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":0},{"@type":"prop","id":"CONDITION","v":"(CBO > 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC <= 20) OR (RFC <= 50) OR (DIT <= 1)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 20 AND WMC <= 50) OR (RFC > 50 AND RFC <= 100) OR (DIT > 1 AND DIT <= 3)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 50 AND WMC <= 101) OR (RFC > 100 AND RFC <= 150) OR (DIT > 3 AND DIT <= 10)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 101 AND WMC <= 120) OR (RFC > 150 AND RFC <= 200) OR (DIT > 10 AND DIT <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":3},{"@type":"prop","id":"CONDITION","v":"(WMC > 120) OR (RFC > 200) OR (DIT > 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM <= 0.6)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.6 AND LCAM <= 0.7)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.7 AND LCAM <= 0.8)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.8 AND LCAM <= 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":2},{"@type":"prop","id":"CONDITION","v":"(LCAM > 0.9)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":0},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC <= 50) OR (NOM <= 20)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":1},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 50 AND LOC <= 300) OR (NOM > 20 AND NOM <= 30)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":2},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 300 AND LOC <= 900) OR (NOM > 30 AND NOM <= 40)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":3},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 900 AND LOC <= 1500) OR (NOM > 40 AND NOM <= 50)"}]},{"list":[{"@type":"bool","id":"enabled","v":true},{"@type":"int","id":"QUALITY_LEVEL","v":4},{"@type":"int","id":"QUALITY_ATTRIBUTE","v":1},{"@type":"prop","id":"CONDITION","v":"(LOC > 1500) OR (NOM > 50)"}]}]},"graph":{"lMap":{"A":{"x":434.0,"y":576.0},"B":{"x":434.0,"y":370.0},"C":{"x":252.0,"y":349.0},"E":{"x":596.0,"y":172.0},"I":{"x":434.0,"y":50.0},"J":{"x":434.0,"y":618.0},"k":{"x":596.0,"y":50.0},"K":{"x":596.0,"y":276.0},"L":{"x":50.0,"y":50.0},"m":{"x":596.0,"y":370.0},"O":{"x":434.0,"y":492.0},"P":{"x":50.0,"y":463.0},"Q":{"x":434.0,"y":328.0},"R":{"x":596.0,"y":484.0},"r":{"x":434.0,"y":660.0},"s":{"x":252.0,"y":50.0},"t":{"x":252.0,"y":576.0},"v":{"x":596.0,"y":432.0},"w":{"x":596.0,"y":224.0},"y":{"x":434.0,"y":534.0},"z":{"x":596.0,"y":318.0}},"vList":[{"type":"w"},{"type":"z"},{"type":"C"},{"type":"L"},{"type":"O"},{"type":"v"},{"type":"B"},{"type":"R"},{"type":"k"},{"type":"J"},{"type":"K"},{"type":"I"},{"type":"P"},{"type":"E"},{"type":"y"},{"type":"m"},{"type":"t"},{"type":"r"},{"type":"Q"},{"type":"A"},{"type":"s"}],"eList":[{"L":[{"s":"B","d":"C","k":3,"w":1}]},{"L":[{"s":"O","d":"t","k":2,"w":1}]},{"L":[{"s":"s","d":"L","k":2,"w":1}]},{"L":[{"s":"y","d":"t","k":2,"w":1}]},{"L":[{"s":"I","d":"k","k":3,"w":1}]},{"L":[{"s":"A","d":"t","k":2,"w":1}]},{"L":[{"s":"J","d":"t","k":2,"w":1}]},{"L":[{"s":"E","d":"Q","k":3,"w":1}]},{"L":[{"s":"w","d":"Q","k":3,"w":1}]},{"L":[{"s":"K","d":"Q","k":3,"w":1}]},{"L":[{"s":"C","d":"P","k":2,"w":1}]},{"L":[{"s":"t","d":"P","k":2,"w":1}]},{"L":[{"s":"z","d":"Q","k":3,"w":1}]},{"L":[{"s":"C","d":"Q","k":3,"w":1}]},{"L":[{"s":"I","d":"s","k":2,"w":1}]},{"L":[{"s":"Q","d":"C","k":3,"w":1}]},{"L":[{"s":"m","d":"Q","k":3,"w":1}]},{"L":[{"s":"v","d":"Q","k":3,"w":1}]},{"L":[{"s":"R","d":"Q","k":3,"w":1}]},{"L":[{"s":"r","d":"t","k":2,"w":1}]}],"clusterMap":{}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.html b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.html new file mode 100644 index 0000000..b3bd112 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.png b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bymodularity.png new file mode 100644 index 0000000000000000000000000000000000000000..555829184522683ac3a3eb7b64ddf1e99ccee337 GIT binary patch literal 22760 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®g4Ee{${mSTCLzx`;P)5Zh3*LM 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 Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bypackage.png b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_bypackage.png new file mode 100644 index 0000000000000000000000000000000000000000..7518d325ee7bb84696e2795a965554ff1eb19e6a GIT binary patch literal 29302 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
    wT zPF+s^ID7mHg-lTQ`4WL(&MlswXbCjcHbp3mb>Y`WYZwrQ(-@1y{ALbzr2(^zOdw#{ z4Thd4f7&NJ#bg@!$-=us=l=G2oYcXakZlJR(pkH4EDYV9R@hj$d7$~W z8LVAn0n>LUNw+f0<_d4Dw{#J66Wiyeb}m16?N(Hoj76f!1BcP5LWLmf3WBMyM+!X% zrs;+A1OB$zsMXs4*YapNDEL->ub;miH#T~Cc^x5o`Q1psvw!&(Hl8e0eqWT0ODRHG zcqu=2tB5rgFsbT{&mC@cNQp_X9*wxwit*(&AC@|W7jiv0JO&(~}Z8oI@ z9P8rdbs)bQ&W7+Ns}yM9QP9iht0-Qwe$hI**i9UGD3~{lU}+<9fu#+_iib{HOncx7 z`d2df6wAtk858>LJZmXnQ=iDNKzoC;%<$<;o1$${ttqg*xaj0eq<3!W1$MWD#PDeT z@R91o0|Ex^DVkduaW2*cUjUz$dbMkC381SS^arA0L4kw~h1IV+V~!-H&C>t$_F%L) z>Ow}C8S{sub{wuC5RK7H@N-4!7&8o%wi5?gO97KJMfzsY@L*pBzP+7w)++^U?^4HA zGqJ&$=)g?CBCx>|4F;3XzbKoerU0%J?}OQ7Io4I)9-G5XsO)g1x$iRI8wP#gUZdft zlsvw&e$fuKu$#&Wm2x>!+&VjL{d2jzpf^XBbf^e(#=`PvDI^NJ_@N4(wG=SEr$N0S zS6osgY;Ljhy{lt>^s%4rc? zL9MktcgrSlr-p*iRrW!jxeCXjIg!mPB#>-MXcL)ap@H$4<7Uj632Hq4@^ZFTMZi@f zZ2{c*vgk%Kk+5UK)=a>fnHX%8qE?_@pBq(vgfHE=VCnqGBQudcw75~V>cwc8tk&Bf zuiU8W=B!CRO}Zk`;xFY!5{w3pb=AutV^9t@3VQiM=Gu#U#q7vg_ZMCrdE=|2 zZ~DpDJI}hm1Y6jHY9Jd5r(WEpRh}OPt(E14u_Tu@V_kGq(=^C=6Y9V^fP?DbV29W3 zYznP^fL`&8XQVuvl9{P`q;u}f3)g6kCw1me(_lUt9b1HP)f!)chcDKnJSWxVBV&S>jH zllbYLa3)uHx>N+OQfLb=>j7mm*7-bZBVYpfe$b*%j*ZvX_MY|p*Q=xFFzUq*Q1w~& z7ugroj22G>yL9jN;VD(Vn+6cJw%HXF5wZEjkDm_z5gfz5tWLlWiNCnZGUoaJcXzG5 zahz2+RS{qM1CS~}t%OijAtJQd(Mq*H~KYdNI;zP z?7e4bs82$vPd?OJq(Vbey&D=@`$GZH@7IB3%l=K;a=POmKiX^E@{R`q?yO!nL znGEjj2Y;WG*;l&;u=M)>R^HuR z`+2^>BoELL&!)c|7Fyr-lD+bapO%y#OjSozW7%qByT5Mdx&$L2NsXFp9%b|D3(~k* z21N|~%@!H3migNJNbn-RLY$k=p9ed68a#TGSjU6k0FHdJ<%()K{#VocbPVnb@5AF( zeesMERtF0g;K%yd!OT}eB6Mnh?#-Rb>EO|MV5{-BJ}&gkYdEH4*ncb^4&N24jaks$ zb?d6=lygZnrgeMWaj&RGEB^MSfj#-Dxw>}T)t5STV2TcGWP#I-bsefsM=;u^XTZ$@ z7#v(3my26CDIAH{of2Kn!cgmnjf)_$OO=g)7wx?s0C0%B$#C2gm*X2>7A(N7bujz& zun6(CUwUK1oDH6m9j>*v@cr=Rylrpc?exaqa61rSi1&z)WJopZ>1$2%^O)xy3H8R9 zbGLs=eE=Bo1^K#qsM#W|!-wkW3IeV!NU-IW8q7~D6wdXrgrw+Zyr%YMd2Ofj*K&% zB6z|;fNYzNd!a#2_^RdL1xCO_!@kt(b{B?Hn%Cp0#=~%lWFu)6Av++nfyG8){DP0{e0#TEz3V~-Cp1h^^vpa;>LZmiTconBQ*XQ0C1FyfYx7^Z2)J&|GscyIBC zVG;6g`}1!F&&dg!`kno`H=a#@>F{#XFYlMWxv75=JhT|x(ahVL1)UDThPy7?B;iWi z(Q5KKEKjLh(wGKq+orYF7#*AoY|Elpmrwmew3K+yEq74#URAk01?J4fT{mHYpnNo& zG5~Kq7Do8r*S9^tcV>BWu&M?>ya-mK-er{vpt8Cac~1%!;Q8-`h1S3A&3&h#)E7(h zaqD22;9A?tpPw%M1RnL%r5|rAe@gE;7YCT@i>jeNoVho7@3u@zeN;6c=(gdw^$@vf z0Ld!~xqxC_M>7Xt8;20<@`E~E$W*Re#HdIpOTzt6@S;1tdi741be2Fn?MIN|BgbV! zWHc)-X|G@bUg%?ipDz7KYqn;l9+p>DF>WZtBFXpx)F&opK5&xInwd4vU!W{MI8lxZ zi(R$ai)I_P+H&3TmU*j18fU?z09!|xsW?|EUvy(#zU4jJw&f7bK+)i@0h^p>T~z#_ zf|oSz>r@zqM|BJ=RUY-yV>>5cq@_1^DgF(aQ>5gskQFXd>i6D zr)p=GYxoz&yprhkWk)#Hg`1xrHFsLTt7PHiLI17w7_Ny6zC9H1fFQ1RLGLP39cX4=7X`NvZ@$s6`J8VYDMf?9)HLm%|8i5isgzKa zn&qb@LS<#!fnZCv1Lyps2Dy!QG&3%ZArj3{<~BP%{yoD4yn0FS0i}5m3305HVEz8l ztu1b_0)-H-6OIiY^Zp!c56?${37iXEd4H#J8h=w31HtblmUGiAbX_4MV8DebsIxIA zYapD6x*)r0HoEDGw9YBWmJ-t9{IGOgxi;n|E)V)~+@@GzFewz|dDgIDr7_=zgu{lz zKj#oy82BxLysof`9wu;iai6(d8FwSj!A>aN<~+Q<;9-duwK`o9+WySt9O76Ek4qq| z5HYj@No>Os;B3J6#+W#ksrdo|rd!OQ;I31}0#_91J?=6HJf02f0xsfpEX$diuCJBd zbWShN$5JYY^x(Ply>;ula4$z21}2J{$Y8114wunls0HFKR9y939~Nee%#jF%5)rzO zp>*v#2ljxciHG&!==Sn55vszS4jwTmyb`6zP*&w=DC@-#U=NPyc!o!kexmpyf(gSK zqW!e4DDnqqEMdtxR*yjmfe~E1GGdKm!a66Nlb+bkB!ke|mq{v`V zZBkguV4k&^)nPT+z>;n}F(E6Ac{l0>@|~5m-!m!35Y3 z$gpw($kx(<;sO^hISY&7{qS1xP+@rWo*9Hmua&E&uFE1&%m)xtmhkoipHKv#L2A|7 zjfOFA*s#*)mGxRvyH!<2RkAIR`QQn|0u&$TU>i{(B4AvzJZ=ACSTjXFoFDi(_e+n*ryj4?Hf43gI-OgA9cu?$An=yoi#`bg%wU(sif6k& zF>uBwG_{$=PsXia!oc7g@!*5u6LPXX2jN`N(v~yiX!TVrs20a1A`#&x$4b|Z;~?Ni z*_PeZsI0&AhY$2uUUANz4IVTQ1b078-NO@jf6Kd*BfuU^lV)P{;zZAr^^2Fejf(>`l;YZ^V_Xzp({!-gG;J7(a4Z=yL z_;*6HZit8)1m5eYkP)~)#G_J^M&{T2K5Ad!`(K^doLk)}f9=inQ>Tn~-U%KtD0nRs iH#4wehp+0bC;cAT-T literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.html b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.html new file mode 100644 index 0000000..6dbe923 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.png b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_byprojectmodule.png new file mode 100644 index 0000000000000000000000000000000000000000..515df5d631315bca3528dabc430d5683e6064fbf GIT binary patch literal 16412 zcmeIZRaYE;6D^!S!9BQ3aEIXT65QS0-8Hzo3{D`pySoIp!QI{626!jWI-lUZI9KOl zX7%cs{&jbCRdv=~|AhX1U?ISJL~eh)fB7P~_ft$* z)l>f>2gX%Z?X|b>vc96D{V_^axGpFH2@`W|b^P>WLCtnq4-+3Eh=ee3M&yb=pCa&n z(}L2>+u^D!gOdUdjsoLzD~r?1%VmqaPC*5_scW$tMH8iR=M(8Cw0!#Zh50G(55~EZp%K$R)B6j^r$tdQG-E=WyIObl zc4Q1bj_&h=1Qi)G+?Rd{60K<@O6bq9=<>USJkRCp@}7MFIN~V&cSx_SjwHR$!DG4w zoL7kRKsF3j2|Wo@H0n=xO8xP}R1GRKVm=R`;YrCB_8YAiQqb>S2qp)R>G3Xh;bFx1 zZzzSq{Yr`&TM9}YH6`(fu=`UhUYl-hx9dHq@ZTUG{fmt|{y*vsHo%Gxo&)z?m+1_) z>#eLF5{D2HYG#y1A7cF*;<7ri6Yl&iz3ALIuKWFm9p=^Y$1xB>(z~E-#fP(*qAK+@ zp7n2{xPETXC>#gnru1D+p7tHlP21A6|Cer~y{d18|6!!>?LFTFW5=c8(J`P5c60cD z60{ClRwdC?bO{(V_jQzyuyT*eM8MBt8q1>@ zSoVLyqJ4on^fWyPn95u>D6eSLWwTq}9&+%j18v&~65zAmT`xn0`)jM*F3WN0hMY>dI>hem?Ncd4a72pE>R#jK-v0h`?~ zWi7tkKEPk`yZ)3+q6v&pQ1*i&YnSnUnEjRWn+Q}}w~~vrw-Asg)?lCW!z@E#2-vGX z5%qcJ*e}?!?{JzD&AWP87-}EALoLMr1(DpUXFs+>Zu6~BCkP^Z`@!3VwZ76E!Rw1~ zI|a2P?18hm$hv*jf;5p(f;}8OLD2BtY#BS^WC9H8{|@+qWcX)OXz{z02NV=?pDmjg zzkWTIa626}bC4JdwIdmuIQPweXlQD`dt)uttZT6EEXXs30`YG=`Aji`Tpbj*NfHE2 zp2Z80F}Ps&r~mEq0q;ZRy%Y=)BL*9fa#|`S2*SniBSwsdni<>Q>6sj@=yxwH+R*Rb z^=FHEc;SK&Ry{+&xY-Y!QEkXbv?

    e)?#=8L4~cVgy+g46RU-*#TSz=7U08EM0z> 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.html b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.html new file mode 100644 index 0000000..a80c77d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.html @@ -0,0 +1 @@ +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.png b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm.png new file mode 100644 index 0000000000000000000000000000000000000000..cffd2ed5cbdf30bb36f7d986689cf18bfe8debc6 GIT binary patch literal 26944 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 R;GdBoCodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm_inheritance.png b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/all_nm_inheritance.png new file mode 100644 index 0000000000000000000000000000000000000000..e822125790a61746d16a7b9e993caf8856630c9f GIT binary patch literal 10186 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/graphlist.js b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/graphlist.js new file mode 100644 index 0000000..00f526b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/graph_htmls/graphlist.js @@ -0,0 +1 @@ +var EQ_graphHTMLText = '

    '; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/Xdonut.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/Xdonut.html new file mode 100644 index 0000000..ab4d736 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/Xdonut.html @@ -0,0 +1,107 @@ + + + + + + + + + + + +
    + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/circlepack.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/circlepack.html new file mode 100644 index 0000000..1c6adf1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/circlepack.html @@ -0,0 +1,113 @@ + + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + +
    +
    + + + + + +
    +
    +
    +
    + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/dependency.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/dependency.html new file mode 100644 index 0000000..05b4312 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/dependency.html @@ -0,0 +1,31 @@ + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donut.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donut.html new file mode 100644 index 0000000..8ac1af3 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donut.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutcharts.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutcharts.html new file mode 100644 index 0000000..cc9471b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutcharts.html @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + +
    + + + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutchartssimple.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/README.md b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/dashboard.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/graphs.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/notifications.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/table.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/template.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartmethod.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartpackage.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartx.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..19733b7 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-core working set: {serialx-core}", "Number of Highly Problematic Classes":0, "Number of Entities":30, "Number of Problematic Classes":4, "Class Lines of Code":2342, "Number of External Packages":7, "Number of Packages":5, "Number of External Entities":74} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..edfbc0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/packagedependency.js @@ -0,0 +1,17 @@ +var matrix = [[0,1,8,1,1],[0,0,2,2,0],[1,0,0,1,0],[3,3,3,0,0],[0,0,0,0,0]] +var packages = [{ +"name": " org.ugp.serialx.converters", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.protocols", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.utils", "color": " #9ecae1" +} +,{ +"name": " org.ugp.serialx", "color": " #c6dbef" +} +,{ +"name": " org.ugp.serialx.converters.imports", "color": " #e6550d" +} +]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/summary_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..f00b487 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 898,count:3}, +{label:"fair quality attributes", color: "#007F24", value: 1663,count:27}]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..b8e8d5a --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,231 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-core working set: {serialx-core}", "value":2342, +"prmetrics":{"5":1,"6":1,"7":1,"8":2,"9":1,"10":1,"11":1}, +"prmetricvalues":{"5":0,"6":30,"7":4,"8":2342,"9":7,"10":5,"11":74}, +"children": [ { +"name": "org.ugp.serialx.converters", "value":571, +"pmetrics":{"4":3,"12":2,"13":1,"14":2,"3":1,"1":2,"0":2,"6":3,"8":2,"2":2,"15":1,"16":2}, +"pmetricvalues":{"4":3,"12":8,"13":2,"14":10,"3":1,"1":2,"0":2,"17":0.166,"6":12,"18":0.167,"8":571,"19":0.667,"2":2,"15":4,"16":288}, +"children":[ +{ +"name": "ProtocolConverter","key": "w","value":157, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, +"metricvalues":{"20":8,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":8,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +}, +{ +"name": "SerializableBase64Converter","key": "z","value":37, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +}, +{ +"name": "DataParser","key": "C","value":117, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +}, +{ +"name": "CharacterConverter","key": "E","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "NumberConverter","key": "v","value":88, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +}, +{ +"name": "VariableParser","key": "B","value":42, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":2,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":2,"3":1,"1":2}, +"metricvalues":{"20":6,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":6,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":2,"3":1,"1":2} +}, +{ +"name": "StringConverter","key": "m","value":51, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +}, +{ +"name": "DataConverter","key": "Q","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +}, +{ +"name": "BooleanConverter","key": "R","value":29, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +}, +{ +"name": "NullConverter","key": "K","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +} +] +},{ +"name": "org.ugp.serialx.protocols", "value":223, +"pmetrics":{"4":2,"12":1,"13":1,"14":2,"3":1,"1":1,"0":1,"6":2,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":3,"13":0,"14":7,"3":1,"1":1,"0":1,"17":0.428,"6":7,"18":0.143,"8":223,"19":0.429,"2":1,"15":4,"16":80}, +"children":[ +{ +"name": "EnumProtocol","key": "O","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "ScopeProtocol","key": "y","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +}, +{ +"name": "MapProtocol","key": "r","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +}, +{ +"name": "SerializationProtocol","key": "t","value":120, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, +"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +}, +{ +"name": "StringProtocol","key": "A","value":33, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +}, +{ +"name": "ListProtocol","key": "J","value":16, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +} +] +},{ +"name": "org.ugp.serialx.utils", "value":493, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":3,"16":2}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":4,"3":1,"1":2,"0":2,"17":0.929,"6":4,"18":0.0,"8":493,"19":0.071,"2":1,"15":13,"16":247}, +"children":[ +{ +"name": "LogProvider","key": "H","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "Registry","key": "P","value":125, +"metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +}, +{ +"name": "StrUtils","key": "N","value":151, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":1,"1":3}, +"metricvalues":{"20":0,"21":0,"38":8,"22":0,"23":0.0,"24":149,"25":0,"26":1,"0":3,"27":1,"28":36,"29":1.0,"30":0.0,"31":1,"32":0.469,"39":0,"33":0,"34":27,"40":8,"35":15,"36":0,"16":93,"37":0,"4":2,"8":151,"2":1,"3":1,"1":3} +}, +{ +"name": "MetaprogrammingUtils","key": "M","value":197, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":4,"27":1,"28":2,"29":1,"30":1,"31":1,"32":4,"33":1,"34":2,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":4,"1":3}, +"metricvalues":{"20":5,"21":0,"38":9,"22":0,"23":0.0,"24":196,"25":0,"26":1,"0":4,"27":1,"28":85,"29":0.0,"30":0.0,"31":0,"32":0.801,"39":4,"33":5,"34":61,"40":5,"35":18,"36":0,"16":96,"37":0,"4":2,"8":197,"2":1,"3":4,"1":3} +} +] +},{ +"name": "org.ugp.serialx", "value":923, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":3,"13":1,"14":3,"3":1,"1":2,"0":2,"17":0.071,"6":4,"18":0.5,"8":923,"19":0.429,"2":1,"15":4,"16":405}, +"children":[ +{ +"name": "GenericScope","key": "L","value":333, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, +"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +}, +{ +"name": "Scope","key": "s","value":353, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":2,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":2,"3":4,"1":5}, +"metricvalues":{"20":6,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":6,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":2,"3":4,"1":5} +}, +{ +"name": "MultimediaSerializer","key": "k","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +}, +{ +"name": "Serializer","key": "I","value":212, +"metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, +"metricvalues":{"20":9,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":9,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +} +] +},{ +"name": "org.ugp.serialx.converters.imports", "value":132, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":0,"13":1,"14":2,"3":1,"1":1,"0":1,"17":0.667,"6":3,"18":0.333,"8":132,"19":0.0,"2":1,"15":1,"16":49}, +"children":[ +{ +"name": "Import","key": "F","value":48, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, +"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +}, +{ +"name": "ImportsProvider","key": "o","value":84, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/table_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..29859d4 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#3)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1Scope ▄ ▄ ▄ ▄35317517349022GenericScope ▄ ▄ ▄ ▄33313814460313Serializer ▄ ▄ ▄ ▄212792153433';var EQ_Table5_Title = 'List of all classes (#30)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1Scope ▄ ▄ ▄ ▄353very-highlow-mediumhighhigh2Serializer ▄ ▄ ▄ ▄212very-highlow-mediumvery-highmedium-high3ProtocolConverter ▄ ▄ ▄ ▄157medium-highlow-mediummedium-highlow-medium4VariableParser ▄ ▄ ▄ ▄42low-mediumlow-mediumlowlow5GenericScope ▄ ▄ ▄ ▄333very-highlowvery-highvery-high6MetaprogrammingUtils ▄ ▄ ▄ ▄197medium-highlowhighlow-medium7StrUtils ▄ ▄ ▄ ▄151medium-highlowlowlow-medium8Registry ▄ ▄ ▄ ▄125medium-highlowlow-mediumlow-medium9NumberConverter ▄ ▄ ▄ ▄88low-mediumlowlow-mediumlow-medium10StringConverter ▄ ▄ ▄ ▄51low-mediumlowlow-mediumlow-medium11StringProtocol ▄ ▄ ▄ ▄33low-mediumlowlowlow12MapProtocol ▄ ▄ ▄ ▄25low-mediumlowlowlow13ScopeProtocol ▄ ▄ ▄ ▄17low-mediumlowlowlow14ListProtocol ▄ ▄ ▄ ▄16low-mediumlowlowlow15EnumProtocol ▄ ▄ ▄ ▄12low-mediumlowlowlow16SerializationProt... ▄ ▄ ▄ ▄120lowlowmedium-highlow-medium17DataParser ▄ ▄ ▄ ▄117lowlowlowlow-medium18ParserRegistry ▄ ▄ ▄ ▄110lowlowlowlow19ImportsProvider ▄ ▄ ▄ ▄84lowlowlowlow-medium20ProtocolRegistry ▄ ▄ ▄ ▄57lowlowlowlow21Imports ▄ ▄ ▄ ▄51lowlowlowlow22Import ▄ ▄ ▄ ▄48lowlowlow-mediumlow23SerializableBase6... ▄ ▄ ▄ ▄37lowlowlowlow24BooleanConverter ▄ ▄ ▄ ▄29lowlowlowlow25MultimediaSerializer ▄ ▄ ▄ ▄25lowlowmedium-highlow26CharacterConverter ▄ ▄ ▄ ▄20lowlowlowlow27LogProvider ▄ ▄ ▄ ▄20lowlowlowlow28NullConverter ▄ ▄ ▄ ▄17lowlowlowlow29DataConverter ▄ ▄ ▄ ▄13lowlowlowlow30IsSelectorScope ▄ ▄ ▄ ▄1lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/report.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/reportforprint.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/sunburst.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/treemap.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/index.html b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/html_report_serialx-core/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/animate.min.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/animate.min.css new file mode 100644 index 0000000..0b6a47d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/animate.min.css @@ -0,0 +1,6 @@ +@charset "UTF-8";/*! +Animate.css - http://daneden.me/animate +Licensed under the MIT license - http://opensource.org/licenses/MIT + +Copyright (c) 2015 Daniel Eden +*/.animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.animated.infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animated.hinge{-webkit-animation-duration:2s;animation-duration:2s}.animated.bounceIn,.animated.bounceOut,.animated.flipOutX,.animated.flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s}@-webkit-keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}@keyframes bounce{100%,20%,53%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1);-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-30px,0);transform:translate3d(0,-30px,0)}70%{-webkit-animation-timing-function:cubic-bezier(0.755,.050,.855,.060);animation-timing-function:cubic-bezier(0.755,.050,.855,.060);-webkit-transform:translate3d(0,-15px,0);transform:translate3d(0,-15px,0)}90%{-webkit-transform:translate3d(0,-4px,0);transform:translate3d(0,-4px,0)}}.bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}@keyframes flash{100%,50%,from{opacity:1}25%,75%{opacity:0}}.flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes pulse{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.pulse{-webkit-animation-name:pulse;animation-name:pulse}@-webkit-keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes rubberBand{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(0.75,1.25,1);transform:scale3d(0.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shake{100%,from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.shake{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}@keyframes swing{20%{-webkit-transform:rotate3d(0,0,1,15deg);transform:rotate3d(0,0,1,15deg)}40%{-webkit-transform:rotate3d(0,0,1,-10deg);transform:rotate3d(0,0,1,-10deg)}60%{-webkit-transform:rotate3d(0,0,1,5deg);transform:rotate3d(0,0,1,5deg)}80%{-webkit-transform:rotate3d(0,0,1,-5deg);transform:rotate3d(0,0,1,-5deg)}100%{-webkit-transform:rotate3d(0,0,1,0deg);transform:rotate3d(0,0,1,0deg)}}.swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes tada{from{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg);transform:scale3d(.9,.9,.9) rotate3d(0,0,1,-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg);transform:scale3d(1.1,1.1,1.1) rotate3d(0,0,1,-3deg)}100%{-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}@keyframes wobble{from{-webkit-transform:none;transform:none}15%{-webkit-transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg);transform:translate3d(-25%,0,0) rotate3d(0,0,1,-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg);transform:translate3d(20%,0,0) rotate3d(0,0,1,3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg);transform:translate3d(-15%,0,0) rotate3d(0,0,1,-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg);transform:translate3d(10%,0,0) rotate3d(0,0,1,2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg);transform:translate3d(-5%,0,0) rotate3d(0,0,1,-1deg)}100%{-webkit-transform:none;transform:none}}.wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{100%,11.1%,from{-webkit-transform:none;transform:none}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(0.390625deg) skewY(0.390625deg);transform:skewX(0.390625deg) skewY(0.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}@keyframes bounceIn{100%,20%,40%,60%,80%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}100%{opacity:1;-webkit-transform:scale3d(1,1,1);transform:scale3d(1,1,1)}}.bounceIn{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInDown{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0);transform:translate3d(0,-3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0);transform:translate3d(0,25px,0)}75%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}90%{-webkit-transform:translate3d(0,5px,0);transform:translate3d(0,5px,0)}100%{-webkit-transform:none;transform:none}}.bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInLeft{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0);transform:translate3d(-3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0);transform:translate3d(25px,0,0)}75%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}90%{-webkit-transform:translate3d(5px,0,0);transform:translate3d(5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}@keyframes bounceInRight{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(3000px,0,0);transform:translate3d(3000px,0,0)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0);transform:translate3d(-25px,0,0)}75%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}90%{-webkit-transform:translate3d(-5px,0,0);transform:translate3d(-5px,0,0)}100%{-webkit-transform:none;transform:none}}.bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes bounceInUp{100%,60%,75%,90%,from{-webkit-animation-timing-function:cubic-bezier(0.215,.61,.355,1);animation-timing-function:cubic-bezier(0.215,.61,.355,1)}from{opacity:0;-webkit-transform:translate3d(0,3000px,0);transform:translate3d(0,3000px,0)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}75%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}90%{-webkit-transform:translate3d(0,-5px,0);transform:translate3d(0,-5px,0)}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}100%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.bounceOut{-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0);transform:translate3d(0,-20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0);transform:translate3d(20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0);transform:translate3d(-20px,0,0)}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0);transform:translate3d(0,20px,0)}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{from{opacity:0}100%{opacity:1}}@keyframes fadeIn{from{opacity:0}100%{opacity:1}}.fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDown{from{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInDownBig{from{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeft{from{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInLeftBig{from{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRight{from{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInRightBig{from{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUp{from{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes fadeInUpBig{from{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}100%{opacity:1;-webkit-transform:none;transform:none}}.fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeOut{from{opacity:1}100%{opacity:0}}@keyframes fadeOut{from{opacity:1}100%{opacity:0}}.fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,-360deg);transform:perspective(400px) rotate3d(0,1,0,-360deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);transform:perspective(400px) translate3d(0,0,150px) rotate3d(0,1,0,-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95);transform:perspective(400px) scale3d(.95,.95,.95);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}100%{-webkit-transform:perspective(400px);transform:perspective(400px);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animated.flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{from{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1,0,0,10deg);transform:perspective(400px) rotate3d(1,0,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-5deg);transform:perspective(400px) rotate3d(1,0,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{from{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-20deg);transform:perspective(400px) rotate3d(0,1,0,-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(0,1,0,10deg);transform:perspective(400px) rotate3d(0,1,0,10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-5deg);transform:perspective(400px) rotate3d(0,1,0,-5deg)}100%{-webkit-transform:perspective(400px);transform:perspective(400px)}}.flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}@keyframes flipOutX{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(1,0,0,-20deg);transform:perspective(400px) rotate3d(1,0,0,-20deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(1,0,0,90deg);transform:perspective(400px) rotate3d(1,0,0,90deg);opacity:0}}.flipOutX{-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}@keyframes flipOutY{from{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotate3d(0,1,0,-15deg);transform:perspective(400px) rotate3d(0,1,0,-15deg);opacity:1}100%{-webkit-transform:perspective(400px) rotate3d(0,1,0,90deg);transform:perspective(400px) rotate3d(0,1,0,90deg);opacity:0}}.flipOutY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}@keyframes lightSpeedIn{from{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg);opacity:1}100%{-webkit-transform:none;transform:none;opacity:1}}.lightSpeedIn{-webkit-animation-name:lightSpeedIn;animation-name:lightSpeedIn;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOut{from{opacity:1}100%{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.lightSpeedOut{-webkit-animation-name:lightSpeedOut;animation-name:lightSpeedOut;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateIn{from{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,-200deg);transform:rotate3d(0,0,1,-200deg);opacity:0}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:none;transform:none;opacity:1}}.rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn}@-webkit-keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft}@-webkit-keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight}@-webkit-keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft}@-webkit-keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}@keyframes rotateInUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-90deg);transform:rotate3d(0,0,1,-90deg);opacity:0}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:none;transform:none;opacity:1}}.rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight}@-webkit-keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}@keyframes rotateOut{from{-webkit-transform-origin:center;transform-origin:center;opacity:1}100%{-webkit-transform-origin:center;transform-origin:center;-webkit-transform:rotate3d(0,0,1,200deg);transform:rotate3d(0,0,1,200deg);opacity:0}}.rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut}@-webkit-keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}@keyframes rotateOutDownLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,45deg);transform:rotate3d(0,0,1,45deg);opacity:0}}.rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft}@-webkit-keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutDownRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight}@-webkit-keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}@keyframes rotateOutUpLeft{from{-webkit-transform-origin:left bottom;transform-origin:left bottom;opacity:1}100%{-webkit-transform-origin:left bottom;transform-origin:left bottom;-webkit-transform:rotate3d(0,0,1,-45deg);transform:rotate3d(0,0,1,-45deg);opacity:0}}.rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft}@-webkit-keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}@keyframes rotateOutUpRight{from{-webkit-transform-origin:right bottom;transform-origin:right bottom;opacity:1}100%{-webkit-transform-origin:right bottom;transform-origin:right bottom;-webkit-transform:rotate3d(0,0,1,90deg);transform:rotate3d(0,0,1,90deg);opacity:0}}.rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight}@-webkit-keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate3d(0,0,1,80deg);transform:rotate3d(0,0,1,80deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate3d(0,0,1,60deg);transform:rotate3d(0,0,1,60deg);-webkit-transform-origin:top left;transform-origin:top left;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}100%{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.hinge{-webkit-animation-name:hinge;animation-name:hinge}@-webkit-keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}@keyframes rollIn{from{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg);transform:translate3d(-100%,0,0) rotate3d(0,0,1,-120deg)}100%{opacity:1;-webkit-transform:none;transform:none}}.rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}@keyframes rollOut{from{opacity:1}100%{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg);transform:translate3d(100%,0,0) rotate3d(0,0,1,120deg)}}.rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{from{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInDown{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInLeft{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInRight{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomInUp{from{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}@keyframes zoomOut{from{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}100%{opacity:0}}.zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0);-webkit-transform-origin:left center;transform-origin:left center}}.zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}100%{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0);-webkit-transform-origin:right center;transform-origin:right center}}.zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(0.55,.055,.675,.19);animation-timing-function:cubic-bezier(0.55,.055,.675,.19)}100%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-transform-origin:center bottom;transform-origin:center bottom;-webkit-animation-timing-function:cubic-bezier(0.175,.885,.32,1);animation-timing-function:cubic-bezier(0.175,.885,.32,1)}}.zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp}@-webkit-keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInDown{from{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInLeft{from{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInRight{from{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}@keyframes slideInUp{from{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}100%{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{from{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}100%{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/bootstrap.min.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/bootstrap.min.css new file mode 100644 index 0000000..d65c66b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.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%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;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:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;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,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/demo.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/demo.css new file mode 100644 index 0000000..febe628 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/demo.css @@ -0,0 +1,61 @@ +@media (min-width: 992px){ + .typo-line{ + padding-left: 140px; + margin-bottom: 40px; + position: relative; + } + + .typo-line .category{ + transform: translateY(-50%); + top: 50%; + left: 0px; + position: absolute; + } +} + +.all-icons [class*="pe-"]{ + font-size: 40px; +} +.all-icons input{ + border: 0; +} +.all-icons .font-icon-detail{ + text-align: center; + padding: 45px 0px 30px; + border: 1px solid #e5e5e5; + border-radius: 6px; + margin: 15px 0; +} +.all-icons .font-icon-detail input{ + margin: 25px auto 0; + width: 100%; + text-align: center; + display: block; + color: #aaa; + font-size: 13px; +} + +#map{ + position:relative; + width:100%; + height: calc(100% - 60px); +} + +.places-buttons .btn{ + margin-bottom: 30px +} +.sidebar .nav > li.active-pro{ + position: absolute; + width: 100%; + bottom: 10px; +} +.sidebar .nav > li.active-pro a{ + background: rgba(255, 255, 255, 0.14); + opacity: 1; + color: #FFFFFF; +} + +.table-upgrade td:nth-child(2), +.table-upgrade td:nth-child(3){ + text-align: center; +} diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/font-awesome.min.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/font-awesome.min.css new file mode 100644 index 0000000..ec53d4d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.2.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.2.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.2.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff?v=4.2.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.2.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.2.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/helptip.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/helptip.css new file mode 100644 index 0000000..8cca39a --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/helptip.css @@ -0,0 +1,148 @@ + +/*------------------------- + Inline help tip +--------------------------*/ + +.help-tip{ + position: relative; + top: 4px; + left: 0px; + text-align: center; + border-radius: 10%; + width: 48px; + height: 24px; + font-size: 14px; + line-height: 26px; + cursor: default; +} + + +.help-tip:before{ + content: url(../img/help.png); + font-weight: bold; + color:#fff; +} + +.help-tip:hover div{ + display:block; + transform-origin: 100% 0%; + + -webkit-animation: fadeIn 0.3s ease-in-out; + animation: fadeIn 0.3s ease-in-out; + +} + +.help-tip div{ + display: none; + text-align: left; + background-color: white; + padding: 20px; + width: 300px; + position: absolute; + border-radius: 3px; + box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.2); + left: -100px; + color: black; + font-size: 13px; + line-height: 1.4; +} + +/* arrow */ +.help-tip div:before{ + position: absolute; + content: ''; + width:0; + height: 0; + border:6px solid transparent; + border-bottom-color: white; + left:100px; + top:-12px; + +} + +.help-tip div:after{ + width:100%; + height:40px; + content:''; + position: absolute; + top:-40px; + left:0; +} + + +@-webkit-keyframes fadeIn { + 0% { + opacity:0; + transform: scale(0.6); + } + + 100% { + opacity:100%; + transform: scale(1); + } +} + +@keyframes fadeIn { + 0% { opacity:0; } + 100% { opacity:100%; } +} + + + +@media (max-width: 1024px) { + #bsaHolder, footer{ display:none;} +} + + .tip-legend .legend-title { + text-align: left; + margin-bottom: 5px; + font-weight: bold; + font-size: 90%; + } + .tip-legend ul { + margin: 0; + margin-bottom: 5px; + padding: 0; + float: left; + list-style: none; + } + .tip-legend ul li { + font-size: 80%; + list-style: lower-roman; + margin-left:25px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li { + + font-size: 80%; + list-style: none; + margin-left: 0px; + line-height: 18px; + margin-bottom: 2px; + } + + .tip-legend ul.tip-legend-labels li span { + + float: left; + height: 16px; + width: 30px; + margin-right: 5px; + margin-left:0px; + border: 1px solid #999; + } + .tip-legend .tip-metric-source { + font-size: 90%; + color: #999; + clear: both; + } + .tip-legend a { + color: #777; + } + + .tip-subsection { + text-align: left; + margin-bottom: 5px; + font-size: 90%; + } \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/light-bootstrap-dashboard.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/light-bootstrap-dashboard.css new file mode 100644 index 0000000..3ce28f5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/light-bootstrap-dashboard.css @@ -0,0 +1,3393 @@ +/* light colors */ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +@-webkit-keyframes spin { + from { + -webkit-transform: rotate(0deg); + } + to { + -webkit-transform: rotate(360deg); + } +} +@-moz-keyframes spin { + from { + -moz-transform: rotate(0deg); + } + to { + -moz-transform: rotate(360deg); + } +} +@-ms-keyframes spin { + from { + -ms-transform: rotate(0deg); + } + to { + -ms-transform: rotate(360deg); + } +} +/* Font Smoothing */ +body, +h1, .h1, +h2, .h2, +h3, .h3, +h4, .h4, +h5, .h5, +h6, .h6, +p, +.navbar, +.brand, +.btn-simple, +.alert, +a, +.td-name, +td, +button.close { + -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + font-family: "Roboto","Helvetica Neue",Arial,sans-serif; + font-weight: 400; +} + +h1, .h1, h2, .h2, h3, .h3, h4, .h4 { + font-weight: 300; + margin: 30px 0 15px; +} + +h1, .h1 { + font-size: 52px; +} + +h2, .h2 { + font-size: 36px; +} + +h3, .h3 { + font-size: 28px; + margin: 20px 0 10px; +} + +h4, .h4 { + font-size: 22px; + line-height: 30px; +} + +h5, .h5 { + font-size: 16px; + margin-bottom: 15px; +} + +h6, .h6 { + font-size: 14px; + font-weight: 600; + text-transform: uppercase; +} + +p { + font-size: 16px; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h4 small, h5 small, h6 small, .h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small, h1 .small, h2 .small, h3 .small, h4 .small, h5 .small, h6 .small, .h1 .small, .h2 .small, .h3 .small, .h4 .small, .h5 .small, .h6 .small { + color: #9A9A9A; + font-weight: 300; + line-height: 1.5; +} + +h1 small, h2 small, h3 small, h1 .small, h2 .small, h3 .small { + font-size: 60%; +} + +h1 .subtitle { + display: block; + margin: 0 0 30px; +} + +.text-muted { + color: #9A9A9A; +} + +.text-primary, .text-primary:hover { + color: #1D62F0 !important; +} + +.text-info, .text-info:hover { + color: #1DC7EA !important; +} + +.text-success, .text-success:hover { + color: #87CB16 !important; +} + +.text-warning, .text-warning:hover { + color: #FF9500 !important; +} + +.text-danger, .text-danger:hover { + color: #FF4A55 !important; +} + +/* General overwrite */ +body, +.wrapper { + min-height: 100vh; + position: relative; +} + +a { + color: #1DC7EA; +} +a:hover, a:focus { + color: #42d0ed; + text-decoration: none; +} + +a:focus, a:active, +button::-moz-focus-inner, +input::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +select::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + outline: 0; +} + +.ui-slider-handle:focus, +.navbar-toggle, +input:focus { + outline: 0 !important; +} + +/* Animations */ +.form-control, +.input-group-addon, +.tagsinput, +.navbar, +.navbar .alert { + -webkit-transition: all 300ms linear; + -moz-transition: all 300ms linear; + -o-transition: all 300ms linear; + -ms-transition: all 300ms linear; + transition: all 300ms linear; +} + +.sidebar .nav a, +.table > tbody > tr .td-actions .btn { + -webkit-transition: all 150ms ease-in; + -moz-transition: all 150ms ease-in; + -o-transition: all 150ms ease-in; + -ms-transition: all 150ms ease-in; + transition: all 150ms ease-in; +} + +.btn { + -webkit-transition: all 100ms ease-in; + -moz-transition: all 100ms ease-in; + -o-transition: all 100ms ease-in; + -ms-transition: all 100ms ease-in; + transition: all 100ms ease-in; +} + +.fa { + width: 18px; + text-align: center; +} + +.margin-top { + margin-top: 50px; +} + +.wrapper { + position: relative; + top: 0; + height: 100vh; +} + +.sidebar { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 260px; + display: block; + z-index: 1; + color: #fff; + font-weight: 200; + background-size: cover; + background-position: center center; +} +.sidebar .sidebar-wrapper { + position: relative; + max-height: none; + min-height: 100%; + overflow: hidden; + width: 260px; + z-index: 4; +} +.sidebar .sidebar-background { + position: absolute; + z-index: 1; + height: 100%; + width: 100%; + display: block; + top: 0; + left: 0; + background-size: cover; + background-position: center center; +} +.sidebar .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar .nav { + margin-top: 20px; +} +.sidebar .nav li > a { + color: #FFFFFF; + margin: 5px 15px; + opacity: .86; + border-radius: 4px; +} +.sidebar .nav li:hover > a { + background: rgba(255, 255, 255, 0.13); + opacity: 1; +} +.sidebar .nav li.active > a { + color: #FFFFFF; + opacity: 1; + background: rgba(255, 255, 255, 0.23); +} +.sidebar .nav p { + margin: 0; + line-height: 30px; + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.sidebar .nav i { + font-size: 28px; + float: left; + margin-right: 15px; + line-height: 30px; + width: 30px; + text-align: center; +} + +.sidebar .logo, +body > .navbar-collapse .logo { + padding: 10px 15px; + border-bottom: 1px solid rgba(255, 255, 255, 0.2); +} +.sidebar .logo p, +body > .navbar-collapse .logo p { + float: left; + font-size: 20px; + margin: 10px 10px; + color: #FFFFFF; + line-height: 20px; + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; +} +.sidebar .logo .simple-text, +body > .navbar-collapse .logo .simple-text { + text-transform: uppercase; + padding: 5px 0px; + display: block; + font-size: 18px; + color: #FFFFFF; + text-align: center; + font-weight: 400; + line-height: 30px; +} +.sidebar .logo-tim, +body > .navbar-collapse .logo-tim { + border-radius: 50%; + border: 1px solid #333; + display: block; + height: 61px; + width: 61px; + float: left; + overflow: hidden; +} +.sidebar .logo-tim img, +body > .navbar-collapse .logo-tim img { + width: 60px; + height: 60px; +} +.sidebar:after, .sidebar:before, +body > .navbar-collapse:after, +body > .navbar-collapse:before { + display: block; + content: ""; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + z-index: 2; +} +.sidebar:before, +body > .navbar-collapse:before { + opacity: .33; + background: #000000; +} +.sidebar:after, +body > .navbar-collapse:after { + background: #787878; + background: -moz-linear-gradient(top, #787878 0%, #343434 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #787878), color-stop(100%, #343434)); + background: -webkit-linear-gradient(top, #787878 0%, #343434 100%); + background: -o-linear-gradient(top, #787878 0%, #343434 100%); + background: -ms-linear-gradient(top, #787878 0%, #343434 100%); + background: linear-gradient(to bottom, #787878 0%, #343434 100%); + background-size: 150% 150%; + z-index: 3; + opacity: 1; +} +.sidebar[data-image]:after, .sidebar.has-image:after, +body > .navbar-collapse[data-image]:after, +body > .navbar-collapse.has-image:after { + opacity: .77; +} +.sidebar[data-color="blue"]:after, +body > .navbar-collapse[data-color="blue"]:after { + background: #1F77D0; + background: -moz-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1F77D0), color-stop(100%, #533ce1)); + background: -webkit-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -o-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: -ms-linear-gradient(top, #1F77D0 0%, #533ce1 100%); + background: linear-gradient(to bottom, #1F77D0 0%, #533ce1 100%); + background-size: 150% 150%; +} +.sidebar[data-color="azure"]:after, +body > .navbar-collapse[data-color="azure"]:after { + background: #1DC7EA; + background: -moz-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #1DC7EA), color-stop(100%, #4091ff)); + background: -webkit-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -o-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: -ms-linear-gradient(top, #1DC7EA 0%, #4091ff 100%); + background: linear-gradient(to bottom, #1DC7EA 0%, #4091ff 100%); + background-size: 150% 150%; +} +.sidebar[data-color="green"]:after, +body > .navbar-collapse[data-color="green"]:after { + background: #87CB16; + background: -moz-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #87CB16), color-stop(100%, #6dc030)); + background: -webkit-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -o-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: -ms-linear-gradient(top, #87CB16 0%, #6dc030 100%); + background: linear-gradient(to bottom, #87CB16 0%, #6dc030 100%); + background-size: 150% 150%; +} +.sidebar[data-color="orange"]:after, +body > .navbar-collapse[data-color="orange"]:after { + background: #FFA534; + background: -moz-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FFA534), color-stop(100%, #ff5221)); + background: -webkit-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -o-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: -ms-linear-gradient(top, #FFA534 0%, #ff5221 100%); + background: linear-gradient(to bottom, #FFA534 0%, #ff5221 100%); + background-size: 150% 150%; +} +.sidebar[data-color="red"]:after, +body > .navbar-collapse[data-color="red"]:after { + background: #FB404B; + background: -moz-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #FB404B), color-stop(100%, #bb0502)); + background: -webkit-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -o-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: -ms-linear-gradient(top, #FB404B 0%, #bb0502 100%); + background: linear-gradient(to bottom, #FB404B 0%, #bb0502 100%); + background-size: 150% 150%; +} +.sidebar[data-color="purple"]:after, +body > .navbar-collapse[data-color="purple"]:after { + background: #9368E9; + background: -moz-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #9368E9), color-stop(100%, #943bea)); + background: -webkit-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -o-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: -ms-linear-gradient(top, #9368E9 0%, #943bea 100%); + background: linear-gradient(to bottom, #9368E9 0%, #943bea 100%); + background-size: 150% 150%; +} + +.main-panel { + background: rgba(203, 203, 210, 0.15); + position: relative; + z-index: 2; + float: right; + width: calc(100% - 260px); + min-height: 100%; +} +.main-panel > .content { + padding: 30px 15px; + min-height: calc(100% - 123px); +} +.main-panel > .footer { + border-top: 1px solid #e7e7e7; +} +.main-panel .navbar { + margin-bottom: 0; +} + +.sidebar, +.main-panel { + overflow: auto; + max-height: 100%; + height: 100%; + -webkit-transition-property: top,bottom; + transition-property: top,bottom; + -webkit-transition-duration: .2s,.2s; + transition-duration: .2s,.2s; + -webkit-transition-timing-function: linear,linear; + transition-timing-function: linear,linear; + -webkit-overflow-scrolling: touch; +} + +.btn { + border-width: 2px; + background-color: transparent; + font-weight: 400; + opacity: 0.8; + filter: alpha(opacity=80); + padding: 8px 16px; + border-color: #888888; + color: #888888; +} +.btn:hover, .btn:focus, .btn:active, .btn.active, .open > .btn.dropdown-toggle { + background-color: transparent; + color: #777777; + border-color: #777777; +} +.btn.disabled, .btn.disabled:hover, .btn.disabled:focus, .btn.disabled.focus, .btn.disabled:active, .btn.disabled.active, .btn:disabled, .btn:disabled:hover, .btn:disabled:focus, .btn:disabled.focus, .btn:disabled:active, .btn:disabled.active, .btn[disabled], .btn[disabled]:hover, .btn[disabled]:focus, .btn[disabled].focus, .btn[disabled]:active, .btn[disabled].active, fieldset[disabled] .btn, fieldset[disabled] .btn:hover, fieldset[disabled] .btn:focus, fieldset[disabled] .btn.focus, fieldset[disabled] .btn:active, fieldset[disabled] .btn.active { + background-color: transparent; + border-color: #888888; +} +.btn.btn-fill { + color: #FFFFFF; + background-color: #888888; + opacity: 1; + filter: alpha(opacity=100); +} +.btn.btn-fill:hover, .btn.btn-fill:focus, .btn.btn-fill:active, .btn.btn-fill.active, .open > .btn.btn-fill.dropdown-toggle { + background-color: #777777; + color: #FFFFFF; +} +.btn.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn .caret { + border-top-color: #888888; +} +.btn:hover, .btn:focus { + opacity: 1; + filter: alpha(opacity=100); + outline: 0 !important; +} +.btn:active, .btn.active, .open > .btn.dropdown-toggle { + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; +} +.btn.btn-icon { + padding: 8px; +} + +.btn-primary { + border-color: #3472F7; + color: #3472F7; +} +.btn-primary:hover, .btn-primary:focus, .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { + background-color: transparent; + color: #1D62F0; + border-color: #1D62F0; +} +.btn-primary.disabled, .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary.disabled:active, .btn-primary.disabled.active, .btn-primary:disabled, .btn-primary:disabled:hover, .btn-primary:disabled:focus, .btn-primary:disabled.focus, .btn-primary:disabled:active, .btn-primary:disabled.active, .btn-primary[disabled], .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, .btn-primary[disabled]:active, .btn-primary[disabled].active, fieldset[disabled] .btn-primary, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus, fieldset[disabled] .btn-primary:active, fieldset[disabled] .btn-primary.active { + background-color: transparent; + border-color: #3472F7; +} +.btn-primary.btn-fill { + color: #FFFFFF; + background-color: #3472F7; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-primary.btn-fill:hover, .btn-primary.btn-fill:focus, .btn-primary.btn-fill:active, .btn-primary.btn-fill.active, .open > .btn-primary.btn-fill.dropdown-toggle { + background-color: #1D62F0; + color: #FFFFFF; +} +.btn-primary.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-primary .caret { + border-top-color: #3472F7; +} + +.btn-success { + border-color: #87CB16; + color: #87CB16; +} +.btn-success:hover, .btn-success:focus, .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { + background-color: transparent; + color: #049F0C; + border-color: #049F0C; +} +.btn-success.disabled, .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success.disabled:active, .btn-success.disabled.active, .btn-success:disabled, .btn-success:disabled:hover, .btn-success:disabled:focus, .btn-success:disabled.focus, .btn-success:disabled:active, .btn-success:disabled.active, .btn-success[disabled], .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, .btn-success[disabled]:active, .btn-success[disabled].active, fieldset[disabled] .btn-success, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus, fieldset[disabled] .btn-success:active, fieldset[disabled] .btn-success.active { + background-color: transparent; + border-color: #87CB16; +} +.btn-success.btn-fill { + color: #FFFFFF; + background-color: #87CB16; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-success.btn-fill:hover, .btn-success.btn-fill:focus, .btn-success.btn-fill:active, .btn-success.btn-fill.active, .open > .btn-success.btn-fill.dropdown-toggle { + background-color: #049F0C; + color: #FFFFFF; +} +.btn-success.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-success .caret { + border-top-color: #87CB16; +} + +.btn-info { + border-color: #1DC7EA; + color: #1DC7EA; +} +.btn-info:hover, .btn-info:focus, .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { + background-color: transparent; + color: #42d0ed; + border-color: #42d0ed; +} +.btn-info.disabled, .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info.disabled:active, .btn-info.disabled.active, .btn-info:disabled, .btn-info:disabled:hover, .btn-info:disabled:focus, .btn-info:disabled.focus, .btn-info:disabled:active, .btn-info:disabled.active, .btn-info[disabled], .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, .btn-info[disabled]:active, .btn-info[disabled].active, fieldset[disabled] .btn-info, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus, fieldset[disabled] .btn-info:active, fieldset[disabled] .btn-info.active { + background-color: transparent; + border-color: #1DC7EA; +} +.btn-info.btn-fill { + color: #FFFFFF; + background-color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-info.btn-fill:hover, .btn-info.btn-fill:focus, .btn-info.btn-fill:active, .btn-info.btn-fill.active, .open > .btn-info.btn-fill.dropdown-toggle { + background-color: #42d0ed; + color: #FFFFFF; +} +.btn-info.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-info .caret { + border-top-color: #1DC7EA; +} + +.btn-warning { + border-color: #FF9500; + color: #FF9500; +} +.btn-warning:hover, .btn-warning:focus, .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { + background-color: transparent; + color: #ED8D00; + border-color: #ED8D00; +} +.btn-warning.disabled, .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning.disabled:active, .btn-warning.disabled.active, .btn-warning:disabled, .btn-warning:disabled:hover, .btn-warning:disabled:focus, .btn-warning:disabled.focus, .btn-warning:disabled:active, .btn-warning:disabled.active, .btn-warning[disabled], .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, .btn-warning[disabled]:active, .btn-warning[disabled].active, fieldset[disabled] .btn-warning, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus, fieldset[disabled] .btn-warning:active, fieldset[disabled] .btn-warning.active { + background-color: transparent; + border-color: #FF9500; +} +.btn-warning.btn-fill { + color: #FFFFFF; + background-color: #FF9500; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-warning.btn-fill:hover, .btn-warning.btn-fill:focus, .btn-warning.btn-fill:active, .btn-warning.btn-fill.active, .open > .btn-warning.btn-fill.dropdown-toggle { + background-color: #ED8D00; + color: #FFFFFF; +} +.btn-warning.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-warning .caret { + border-top-color: #FF9500; +} + +.btn-danger { + border-color: #FF4A55; + color: #FF4A55; +} +.btn-danger:hover, .btn-danger:focus, .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { + background-color: transparent; + color: #EE2D20; + border-color: #EE2D20; +} +.btn-danger.disabled, .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger.disabled:active, .btn-danger.disabled.active, .btn-danger:disabled, .btn-danger:disabled:hover, .btn-danger:disabled:focus, .btn-danger:disabled.focus, .btn-danger:disabled:active, .btn-danger:disabled.active, .btn-danger[disabled], .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, .btn-danger[disabled]:active, .btn-danger[disabled].active, fieldset[disabled] .btn-danger, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus, fieldset[disabled] .btn-danger:active, fieldset[disabled] .btn-danger.active { + background-color: transparent; + border-color: #FF4A55; +} +.btn-danger.btn-fill { + color: #FFFFFF; + background-color: #FF4A55; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-danger.btn-fill:hover, .btn-danger.btn-fill:focus, .btn-danger.btn-fill:active, .btn-danger.btn-fill.active, .open > .btn-danger.btn-fill.dropdown-toggle { + background-color: #EE2D20; + color: #FFFFFF; +} +.btn-danger.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-danger .caret { + border-top-color: #FF4A55; +} + +.btn-neutral { + border-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral:hover, .btn-neutral:focus, .btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: transparent; + color: #FFFFFF; + border-color: #FFFFFF; +} +.btn-neutral.disabled, .btn-neutral.disabled:hover, .btn-neutral.disabled:focus, .btn-neutral.disabled.focus, .btn-neutral.disabled:active, .btn-neutral.disabled.active, .btn-neutral:disabled, .btn-neutral:disabled:hover, .btn-neutral:disabled:focus, .btn-neutral:disabled.focus, .btn-neutral:disabled:active, .btn-neutral:disabled.active, .btn-neutral[disabled], .btn-neutral[disabled]:hover, .btn-neutral[disabled]:focus, .btn-neutral[disabled].focus, .btn-neutral[disabled]:active, .btn-neutral[disabled].active, fieldset[disabled] .btn-neutral, fieldset[disabled] .btn-neutral:hover, fieldset[disabled] .btn-neutral:focus, fieldset[disabled] .btn-neutral.focus, fieldset[disabled] .btn-neutral:active, fieldset[disabled] .btn-neutral.active { + background-color: transparent; + border-color: #FFFFFF; +} +.btn-neutral.btn-fill { + color: #FFFFFF; + background-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus, .btn-neutral.btn-fill:active, .btn-neutral.btn-fill.active, .open > .btn-neutral.btn-fill.dropdown-toggle { + background-color: #FFFFFF; + color: #FFFFFF; +} +.btn-neutral.btn-fill .caret { + border-top-color: #FFFFFF; +} +.btn-neutral .caret { + border-top-color: #FFFFFF; +} +.btn-neutral:active, .btn-neutral.active, .open > .btn-neutral.dropdown-toggle { + background-color: #FFFFFF; + color: #888888; +} +.btn-neutral.btn-fill, .btn-neutral.btn-fill:hover, .btn-neutral.btn-fill:focus { + color: #888888; +} +.btn-neutral.btn-simple:active, .btn-neutral.btn-simple.active { + background-color: transparent; +} + +.btn:disabled, .btn[disabled], .btn.disabled { + opacity: 0.5; + filter: alpha(opacity=50); +} + +.btn-round { + border-width: 1px; + border-radius: 30px !important; + padding: 9px 18px; +} +.btn-round.btn-icon { + padding: 9px; +} + +.btn-simple { + border: 0; + font-size: 16px; + padding: 8px 16px; +} +.btn-simple.btn-icon { + padding: 8px; +} + +.btn-lg { + font-size: 18px; + border-radius: 6px; + padding: 14px 30px; + font-weight: 400; +} +.btn-lg.btn-round { + padding: 15px 30px; +} +.btn-lg.btn-simple { + padding: 16px 30px; +} + +.btn-sm { + font-size: 12px; + border-radius: 3px; + padding: 5px 10px; +} +.btn-sm.btn-round { + padding: 6px 10px; +} +.btn-sm.btn-simple { + padding: 7px 10px; +} + +.btn-xs { + font-size: 12px; + border-radius: 3px; + padding: 1px 5px; +} +.btn-xs.btn-round { + padding: 2px 5px; +} +.btn-xs.btn-simple { + padding: 3px 5px; +} + +.btn-wd { + min-width: 140px; +} + +.btn-group.select { + width: 100%; +} + +.btn-group.select .btn { + text-align: left; +} + +.btn-group.select .caret { + position: absolute; + top: 50%; + margin-top: -1px; + right: 8px; +} + +.form-control::-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-moz-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control::-webkit-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control:-ms-input-placeholder { + color: #DDDDDD; + opacity: 1; + filter: alpha(opacity=100); +} + +.form-control { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; + color: #565656; + padding: 8px 12px; + height: 40px; + -webkit-box-shadow: none; + box-shadow: none; +} +.form-control:focus { + background-color: #FFFFFF; + border: 1px solid #AAAAAA; + -webkit-box-shadow: none; + box-shadow: none; + outline: 0 !important; + color: #333333; +} +.has-success .form-control, .has-error .form-control, .has-success .form-control:focus, .has-error .form-control:focus { + border-color: #E3E3E3; + -webkit-box-shadow: none; + box-shadow: none; +} +.has-success .form-control { + color: #87CB16; +} +.has-success .form-control:focus { + border-color: #87CB16; +} +.has-error .form-control { + color: #FF4A55; +} +.has-error .form-control:focus { + border-color: #FF4A55; +} +.form-control + .form-control-feedback { + border-radius: 6px; + font-size: 14px; + margin-top: -7px; + position: absolute; + right: 10px; + top: 50%; + vertical-align: middle; +} +.open .form-control { + border-radius: 4px 4px 0 0; + border-bottom-color: transparent; +} + +.input-lg { + height: 55px; + padding: 14px 30px; +} + +.has-error .form-control-feedback { + color: #FF4A55; +} + +.has-success .form-control-feedback { + color: #87CB16; +} + +.input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; + border-radius: 4px; +} +.has-success .input-group-addon, .has-error .input-group-addon { + background-color: #FFFFFF; + border: 1px solid #E3E3E3; +} +.has-error .form-control:focus + .input-group-addon { + border-color: #FF4A55; + color: #FF4A55; +} +.has-success .form-control:focus + .input-group-addon { + border-color: #87CB16; + color: #87CB16; +} +.form-control:focus + .input-group-addon, .form-control:focus ~ .input-group-addon { + background-color: #FFFFFF; + border-color: #9A9A9A; +} + +.input-group .form-control:first-child, +.input-group-addon:first-child, +.input-group-btn:first-child > .dropdown-toggle, +.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) { + border-right: 0 none; +} + +.input-group .form-control:last-child, +.input-group-addon:last-child, +.input-group-btn:last-child > .dropdown-toggle, +.input-group-btn:first-child > .btn:not(:first-child) { + border-left: 0 none; +} + +.form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { + background-color: #F5F5F5; + color: #888888; + cursor: not-allowed; +} + +.input-group-btn .btn { + border-width: 1px; + padding: 9px 16px; +} + +.input-group-btn .btn-default:not(.btn-fill) { + border-color: #DDDDDD; +} + +.input-group-btn:last-child > .btn { + margin-left: 0; +} + +.input-group-focus .input-group-addon { + border-color: #9A9A9A; +} + +.alert { + border: 0; + border-radius: 0; + color: #FFFFFF; + padding: 10px 15px; + font-size: 14px; +} +.container .alert { + border-radius: 4px; +} +.navbar .alert { + border-radius: 0; + left: 0; + position: absolute; + right: 0; + top: 85px; + width: 100%; + z-index: 3; +} +.navbar:not(.navbar-transparent) .alert { + top: 70px; +} +.alert span[data-notify="icon"] { + font-size: 30px; + display: block; + left: 15px; + position: absolute; + top: 50%; + margin-top: -15px; +} +.alert button.close { + position: absolute; + right: 10px; + top: 50%; + margin-top: -13px; + z-index: 1033; + background-color: #FFFFFF; + display: block; + border-radius: 50%; + opacity: .4; + line-height: 11px; + width: 25px; + height: 25px; + outline: 0 !important; + text-align: center; + padding: 3px; + font-weight: 300; +} +.alert button.close:hover { + opacity: .55; +} +.alert .close ~ span { + display: block; + max-width: 89%; +} +.alert[data-notify="container"] { + padding: 10px 10px 10px 20px; + border-radius: 4px; +} +.alert.alert-with-icon { + padding-left: 65px; +} + +.alert-info { + background-color: #63d8f1; +} + +.alert-success { + background-color: #a1e82c; +} + +.alert-warning { + background-color: #ffbc67; +} + +.alert-danger { + background-color: #fc727a; +} + +.table .radio, +.table .checkbox { + position: relative; + height: 20px; + display: block; + width: 20px; + padding: 0px 0px; + margin: 0px 5px; + text-align: center; +} +.table .radio .icons, +.table .checkbox .icons { + left: 5px; +} +.table > thead > tr > th, +.table > tbody > tr > th, +.table > tfoot > tr > th, +.table > thead > tr > td, +.table > tbody > tr > td, +.table > tfoot > tr > td { + padding: 12px 8px; + vertical-align: middle; +} +.table > thead > tr > th { + border-bottom-width: 1px; + font-size: 12px; + text-transform: uppercase; + color: #9A9A9A; + font-weight: 400; + padding-bottom: 5px; +} +.table .td-actions .btn { + opacity: 0.36; + filter: alpha(opacity=36); +} +.table .td-actions .btn.btn-xs { + padding-left: 3px; + padding-right: 3px; +} +.table .td-actions { + min-width: 90px; +} +.table > tbody > tr { + position: relative; +} +.table > tbody > tr:hover .td-actions .btn { + opacity: 1; + filter: alpha(opacity=100); +} + +/* Checkbox and radio */ +.checkbox, +.radio { + margin-bottom: 12px; + padding-left: 32px; + position: relative; + -webkit-transition: color 0.25s linear; + transition: color 0.25s linear; + font-size: 14px; + font-weight: normal; + line-height: 1.5; + color: #333333; +} + +.checkbox input, +.radio input { + outline: none !important; + display: none; +} + +.checkbox .icons, +.radio .icons { + color: #DDDDDD; + display: block; + height: 20px; + left: 0; + position: absolute; + top: 0; + width: 20px; + text-align: center; + line-height: 21px; + font-size: 20px; + cursor: pointer; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox .icons .first-icon, +.radio .icons .first-icon, +.checkbox .icons .second-icon, +.radio .icons .second-icon { + display: inline-table; + position: absolute; + left: 0; + top: 0; + background-color: transparent; + margin: 0; + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox .icons .second-icon, +.radio .icons .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover, +.radio:hover { + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox:hover .first-icon, +.radio:hover .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox:hover .second-icon, +.radio:hover .second-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.checked, +.radio.checked { + color: #1DC7EA; +} + +.checkbox.checked .first-icon, +.radio.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.checked .second-icon, +.radio.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #1DC7EA; + -webkit-transition: color 0.2s linear; + transition: color 0.2s linear; +} + +.checkbox.disabled, +.radio.disabled { + cursor: default; + color: #DDDDDD !important; +} + +.checkbox.disabled .icons, +.radio.disabled .icons { + color: #DDDDDD !important; +} + +.checkbox.disabled .first-icon, +.radio.disabled .first-icon { + opacity: 1; + filter: alpha(opacity=100); +} + +.checkbox.disabled .second-icon, +.radio.disabled .second-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .icons, +.radio.disabled.checked .icons { + color: #DDDDDD; +} + +.checkbox.disabled.checked .first-icon, +.radio.disabled.checked .first-icon { + opacity: 0; + filter: alpha(opacity=0); +} + +.checkbox.disabled.checked .second-icon, +.radio.disabled.checked .second-icon { + opacity: 1; + filter: alpha(opacity=100); + color: #D9D9D9; +} + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ +.has-switch { + border-radius: 30px; + cursor: pointer; + display: inline-block; + line-height: 1.72222; + overflow: hidden; + position: relative; + text-align: left; + width: 60px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + /* this code is for fixing safari bug with hidden overflow for border-radius */ + -webkit-mask: url("../img/mask.png") 0 0 no-repeat; + -webkit-mask-size: 60px 24px; + mask: url("../img/mask.png") 0 0 no-repeat; +} + +.has-switch.deactivate { + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default !important; +} + +.has-switch.deactivate label, +.has-switch.deactivate span { + cursor: default !important; +} + +.has-switch > div { + position: relative; + top: 0; + width: 100px; +} + +.has-switch > div.switch-animate { + -webkit-transition: left 0.25s ease-out; + transition: left 0.25s ease-out; +} + +.has-switch > div.switch-off { + left: -35px; +} + +.has-switch > div.switch-on { + left: 0; +} + +.has-switch > div label { + background-color: #FFFFFF; + background: white; + background: -moz-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #f1f1f2)); + background: -webkit-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -o-linear-gradient(top, white 0%, #f1f1f2 100%); + background: -ms-linear-gradient(top, white 0%, #f1f1f2 100%); + background: linear-gradient(to bottom, white 0%, #f1f1f2 100%); + background-size: 150% 150%; + box-shadow: 0 1px 1px #FFFFFF inset, 0 1px 1px rgba(0, 0, 0, 0.25); + cursor: pointer; +} + +.has-switch input[type=checkbox] { + display: none; +} + +.has-switch span { + /* box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2) inset; */ + cursor: pointer; + float: left; + font-size: 11px; + font-weight: 400; + height: 24px; + line-height: 15px; + margin: 0; + padding-bottom: 6px; + padding-top: 5px; + position: relative; + text-align: center; + text-indent: -10px; + width: 50%; + z-index: 1; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch span.switch-left { + background-color: #1DC7EA; + border-left: 1px solid transparent; + border-radius: 30px 0 0 30px; + color: #FFFFFF; +} + +.has-switch .switch-off span.switch-left { + background-color: #DDDDDD; +} + +.has-switch span.switch-right { + border-radius: 0 30px 30px 0; + background-color: #1DC7EA; + color: #ffffff; + text-indent: 1px; +} + +.has-switch .switch-off span.switch-right { + background-color: #DDDDDD; +} + +.has-switch label { + border-radius: 12px; + float: left; + height: 22px; + margin: 1px -13px; + padding: 0; + position: relative; + transition: all 0.25s ease-out 0s; + vertical-align: middle; + width: 22px; + z-index: 100; + -webkit-transition: 0.25s ease-out; + transition: 0.25s ease-out; +} + +.has-switch .switch-on .fa-check:before { + margin-left: 10px; +} + +.has-switch:hover .switch-on label { + margin: 1px -17px; + width: 26px; +} + +.has-switch:hover .switch-off label { + margin: 1px -13px; + width: 26px; +} + +.nav > li > a:hover, +.nav > li > a:focus { + background-color: transparent; +} + +.navbar { + border: 0; + font-size: 16px; + border-radius: 0; +} +.navbar .navbar-brand { + font-weight: 400; + margin: 5px 0px; + padding: 15px 15px; + font-size: 20px; +} +.navbar .navbar-nav > li > a { + padding: 10px 15px; + margin: 10px 3px; + position: relative; +} +.navbar .navbar-nav > li > a.btn { + margin: 15px 3px; + padding: 8px 16px; +} +.navbar .navbar-nav > li > a.btn-round { + margin: 16px 3px; +} +.navbar .navbar-nav > li > a [class^="fa"] { + font-size: 19px; + position: relative; + line-height: 16px; + top: 1px; +} +.navbar .navbar-nav .notification { + position: absolute; + background-color: #FB404B; + text-align: center; + border-radius: 10px; + min-width: 18px; + padding: 0 5px; + height: 18px; + font-size: 12px; + color: #FFFFFF; + font-weight: bold; + line-height: 18px; + top: 0px; + left: 7px; +} +.navbar .btn { + margin: 15px 3px; + font-size: 14px; +} +.navbar .btn-simple { + font-size: 16px; +} +.navbar.fixed { + width: calc(100% - $sidebar-width); + right: 0; + left: auto; + border-radius: 0; +} + +.navbar-nav > li > .dropdown-menu { + border-radius: 10px; + margin-top: -5px; +} + +.navbar-transparent .navbar-brand, [class*="navbar-ct"] .navbar-brand { + color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .navbar-brand:focus, .navbar-transparent .navbar-brand:hover, [class*="navbar-ct"] .navbar-brand:focus, [class*="navbar-ct"] .navbar-brand:hover { + background-color: transparent; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav > li > a:not(.btn), [class*="navbar-ct"] .navbar-nav > li > a:not(.btn) { + color: #FFFFFF; + border-color: #FFFFFF; + opacity: 0.8; + filter: alpha(opacity=80); +} +.navbar-transparent .navbar-nav > .active > a:not(.btn), +.navbar-transparent .navbar-nav > .active > a:hover:not(.btn), +.navbar-transparent .navbar-nav > .active > a:focus:not(.btn), +.navbar-transparent .navbar-nav > li > a:hover:not(.btn), +.navbar-transparent .navbar-nav > li > a:focus:not(.btn), [class*="navbar-ct"] .navbar-nav > .active > a:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > .active > a:focus:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:hover:not(.btn), +[class*="navbar-ct"] .navbar-nav > li > a:focus:not(.btn) { + background-color: transparent; + border-radius: 3px; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .navbar-nav .nav > li > a.btn:hover, [class*="navbar-ct"] .navbar-nav .nav > li > a.btn:hover { + background-color: transparent; +} +.navbar-transparent .navbar-nav > .dropdown > a .caret, +.navbar-transparent .navbar-nav > .dropdown > a:hover .caret, +.navbar-transparent .navbar-nav > .dropdown > a:focus .caret, [class*="navbar-ct"] .navbar-nav > .dropdown > a .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:hover .caret, +[class*="navbar-ct"] .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} +.navbar-transparent .navbar-nav > .open > a, +.navbar-transparent .navbar-nav > .open > a:hover, +.navbar-transparent .navbar-nav > .open > a:focus, [class*="navbar-ct"] .navbar-nav > .open > a, +[class*="navbar-ct"] .navbar-nav > .open > a:hover, +[class*="navbar-ct"] .navbar-nav > .open > a:focus { + background-color: transparent; + color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-transparent .btn-default, [class*="navbar-ct"] .btn-default { + color: #FFFFFF; + border-color: #FFFFFF; +} +.navbar-transparent .btn-default.btn-fill, [class*="navbar-ct"] .btn-default.btn-fill { + color: #9A9A9A; + background-color: #FFFFFF; + opacity: 0.9; + filter: alpha(opacity=90); +} +.navbar-transparent .btn-default.btn-fill:hover, +.navbar-transparent .btn-default.btn-fill:focus, +.navbar-transparent .btn-default.btn-fill:active, +.navbar-transparent .btn-default.btn-fill.active, +.navbar-transparent .open .dropdown-toggle.btn-fill.btn-default, [class*="navbar-ct"] .btn-default.btn-fill:hover, +[class*="navbar-ct"] .btn-default.btn-fill:focus, +[class*="navbar-ct"] .btn-default.btn-fill:active, +[class*="navbar-ct"] .btn-default.btn-fill.active, +[class*="navbar-ct"] .open .dropdown-toggle.btn-fill.btn-default { + border-color: #FFFFFF; + opacity: 1; + filter: alpha(opacity=100); +} + +.navbar-transparent .dropdown-menu .divider { + background-color: rgba(255, 255, 255, 0.2); +} + +.nav-open .nav .caret { + border-bottom-color: #FFFFFF; + border-top-color: #FFFFFF; +} + +.navbar-default { + background-color: rgba(255, 255, 255, 0.96); + border-bottom: 1px solid rgba(0, 0, 0, 0.1); +} +.navbar-default .navbar-nav > li > a:not(.btn) { + color: #9A9A9A; +} +.navbar-default .navbar-nav > .active > a, +.navbar-default .navbar-nav > .active > a:not(.btn):hover, +.navbar-default .navbar-nav > .active > a:not(.btn):focus, +.navbar-default .navbar-nav > li > a:not(.btn):hover, +.navbar-default .navbar-nav > li > a:not(.btn):focus { + background-color: transparent; + border-radius: 3px; + color: #1DC7EA; + opacity: 1; + filter: alpha(opacity=100); +} +.navbar-default .navbar-nav > .dropdown > a:hover .caret, +.navbar-default .navbar-nav > .dropdown > a:focus .caret { + border-bottom-color: #1DC7EA; + border-top-color: #1DC7EA; +} +.navbar-default .navbar-nav > .open > a, +.navbar-default .navbar-nav > .open > a:hover, +.navbar-default .navbar-nav > .open > a:focus { + background-color: transparent; + color: #1DC7EA; +} +.navbar-default .navbar-nav .navbar-toggle:hover, .navbar-default .navbar-nav .navbar-toggle:focus { + background-color: transparent; +} +.navbar-default:not(.navbar-transparent) .btn-default:hover { + color: #1DC7EA; + border-color: #1DC7EA; +} +.navbar-default:not(.navbar-transparent) .btn-neutral, .navbar-default:not(.navbar-transparent) .btn-neutral:hover, .navbar-default:not(.navbar-transparent) .btn-neutral:active { + color: #9A9A9A; +} + +/* Navbar with icons */ +.navbar-icons.navbar .navbar-brand { + margin-top: 12px; + margin-bottom: 12px; +} +.navbar-icons .navbar-nav > li > a { + text-align: center; + padding: 6px 15px; + margin: 6px 3px; +} +.navbar-icons .navbar-nav [class^="pe"] { + font-size: 30px; + position: relative; +} +.navbar-icons .navbar-nav p { + margin: 3px 0 0; +} + +.navbar-form { + -webkit-box-shadow: none; + box-shadow: none; +} +.navbar-form .form-control { + border-radius: 0; + border: 0; + padding: 0; + background-color: transparent; + height: 22px; + font-size: 16px; + line-height: 1.5; + color: #E3E3E3; +} +.navbar-transparent .navbar-form .form-control, [class*="navbar-ct"] .navbar-form .form-control { + color: #FFFFFF; + border: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.6); +} + +.navbar-ct-blue { + background-color: #4091e2; +} + +.navbar-ct-azure { + background-color: #63d8f1; +} + +.navbar-ct-green { + background-color: #a1e82c; +} + +.navbar-ct-orange { + background-color: #ffbc67; +} + +.navbar-ct-red { + background-color: #fc727a; +} + +.navbar-transparent { + padding-top: 15px; + background-color: transparent; + border-bottom: 1px solid transparent; +} + +.navbar-toggle { + margin-top: 19px; + margin-bottom: 19px; + border: 0; +} +.navbar-toggle .icon-bar { + background-color: #FFFFFF; +} +.navbar-toggle .navbar-collapse, +.navbar-toggle .navbar-form { + border-color: transparent; +} +.navbar-toggle.navbar-default .navbar-toggle:hover, .navbar-toggle.navbar-default .navbar-toggle:focus { + background-color: transparent; +} + +.footer { + background-color: #FFFFFF; + line-height: 20px; +} +.footer nav > ul { + list-style: none; + margin: 0; + padding: 0; + font-weight: normal; +} +.footer nav > ul a:not(.btn) { + color: #9A9A9A; + display: block; + margin-bottom: 3px; +} +.footer nav > ul a:not(.btn):hover, .footer nav > ul a:not(.btn):focus { + color: #777777; +} +.footer .social-area { + padding: 15px 0; +} +.footer .social-area h5 { + padding-bottom: 15px; +} +.footer .social-area > a:not(.btn) { + color: #9A9A9A; + display: inline-block; + vertical-align: top; + padding: 10px 5px; + font-size: 20px; + font-weight: normal; + line-height: 20px; + text-align: center; +} +.footer .social-area > a:not(.btn):hover, .footer .social-area > a:not(.btn):focus { + color: #777777; +} +.footer .copyright { + color: #777777; + padding: 10px 15px; + margin: 10px 3px; + line-height: 20px; + font-size: 14px; +} +.footer hr { + border-color: #DDDDDD; +} +.footer .title { + color: #777777; +} + +.footer-default { + background-color: #F5F5F5; +} + +.footer:not(.footer-big) nav > ul { + font-size: 14px; +} +.footer:not(.footer-big) nav > ul li { + margin-left: 20px; + float: left; +} +.footer:not(.footer-big) nav > ul a { + padding: 10px 0px; + margin: 10px 10px 10px 0px; +} + +.dropdown-menu { + visibility: hidden; + margin: 0; + padding: 0; + border-radius: 10px; + display: block; + z-index: 9000; + position: absolute; + opacity: 0; + filter: alpha(opacity=0); + -webkit-box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); + box-shadow: 1px 2px 3px rgba(0, 0, 0, 0.125); +} +.open .dropdown-menu { + opacity: 1; + filter: alpha(opacity=100); + visibility: visible; +} +.select .dropdown-menu { + border-radius: 0 0 10px 10px; + -webkit-box-shadow: none; + box-shadow: none; + -webkit-transform-origin: 50% -40px; + -moz-transform-origin: 50% -40px; + -o-transform-origin: 50% -40px; + -ms-transform-origin: 50% -40px; + transform-origin: 50% -40px; + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transition: all 150ms linear; + -moz-transition: all 150ms linear; + -o-transition: all 150ms linear; + -ms-transition: all 150ms linear; + transition: all 150ms linear; + margin-top: -20px; +} +.select.open .dropdown-menu { + margin-top: -1px; +} +.dropdown-menu > li > a { + padding: 8px 16px; + color: #333333; +} +.dropdown-menu > li > a img { + margin-top: -3px; +} +.dropdown-menu > li > a:focus { + outline: 0 !important; +} +.btn-group.select .dropdown-menu { + min-width: 100%; +} +.dropdown-menu > li:first-child > a { + border-top-left-radius: 10px; + border-top-right-radius: 10px; +} +.dropdown-menu > li:last-child > a { + border-bottom-left-radius: 10px; + border-bottom-right-radius: 10px; +} +.select .dropdown-menu > li:first-child > a { + border-radius: 0; + border-bottom: 0 none; +} +.dropdown-menu > li > a:hover, +.dropdown-menu > li > a:focus { + background-color: #F5F5F5; + color: #333333; + opacity: 1; + text-decoration: none; +} +.dropdown-menu.dropdown-blue > li > a:hover, .dropdown-menu.dropdown-blue > li > a:focus { + background-color: rgba(52, 114, 247, 0.2); +} +.dropdown-menu.dropdown-azure > li > a:hover, .dropdown-menu.dropdown-azure > li > a:focus { + background-color: rgba(29, 199, 234, 0.2); +} +.dropdown-menu.ct-green > li > a:hover, .dropdown-menu.ct-green > li > a:focus { + background-color: rgba(135, 203, 22, 0.2); +} +.dropdown-menu.dropdown-orange > li > a:hover, .dropdown-menu.dropdown-orange > li > a:focus { + background-color: rgba(255, 149, 0, 0.2); +} +.dropdown-menu.dropdown-red > li > a:hover, .dropdown-menu.dropdown-red > li > a:focus { + background-color: rgba(255, 74, 85, 0.2); +} + +.dropdown-with-icons > li > a { + padding-left: 0px; + line-height: 28px; +} +.dropdown-with-icons i { + text-align: center; + line-height: 28px; + float: left; +} +.dropdown-with-icons i[class^="pe-"] { + font-size: 24px; + width: 46px; +} +.dropdown-with-icons i[class^="fa"] { + font-size: 14px; + width: 38px; +} + +.btn-group.select { + overflow: hidden; +} + +.btn-group.select.open { + overflow: visible; +} + +.card { + border-radius: 4px; + box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), 0 0 0 1px rgba(63, 63, 68, 0.1); + background-color: #FFFFFF; + margin-bottom: 30px; +} +.card .image { + width: 100%; + overflow: hidden; + height: 260px; + border-radius: 4px 4px 0 0; + position: relative; + -webkit-transform-style: preserve-3d; + -moz-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.card .image img { + width: 100%; +} +.card .filter { + position: absolute; + z-index: 2; + background-color: rgba(0, 0, 0, 0.68); + top: 0; + left: 0; + width: 100%; + height: 100%; + text-align: center; + opacity: 0; + filter: alpha(opacity=0); +} +.card .filter .btn { + position: relative; + top: 50%; + -webkit-transform: translateY(-50%); + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} +.card:hover .filter { + opacity: 1; + filter: alpha(opacity=100); +} +.card .btn-hover { + opacity: 0; + filter: alpha(opacity=0); +} +.card:hover .btn-hover { + opacity: 1; + filter: alpha(opacity=100); +} +.card .content { + padding: 15px 15px 10px 15px; +} +.card .header { + padding: 15px 15px 0; +} +.card .category, +.card label { + font-size: 14px; + font-weight: 400; + color: #9A9A9A; + margin-bottom: 0px; +} +.card .category i, +.card label i { + font-size: 16px; +} +.card label { + font-size: 12px; + margin-bottom: 5px; + text-transform: uppercase; +} +.card .title { + margin: 0; + color: #333333; + font-weight: 300; +} +.card .avatar { + width: 30px; + height: 30px; + overflow: hidden; + border-radius: 50%; + margin-right: 5px; +} +.card .description { + font-size: 14px; + color: #333; +} +.card .footer { + padding: 0; + background-color: transparent; + line-height: 30px; +} +.card .footer .legend { + padding: 5px 0; +} +.card .footer hr { + margin-top: 5px; + margin-bottom: 5px; +} +.card .stats { + color: #a9a9a9; +} +.card .footer div { + display: inline-block; +} +.card .author { + font-size: 12px; + font-weight: 600; + text-transform: uppercase; +} +.card .author i { + font-size: 14px; +} +.card h6 { + font-size: 12px; + margin: 0; +} +.card.card-separator:after { + height: 100%; + right: -15px; + top: 0; + width: 1px; + background-color: #DDDDDD; + content: ""; + position: absolute; +} +.card .ct-chart { + margin: 30px 0 30px; + height: 245px; +} +.card .table tbody td:first-child, +.card .table thead th:first-child { + padding-left: 15px; +} +.card .table tbody td:last-child, +.card .table thead th:last-child { + padding-right: 15px; +} +.card .alert { + border-radius: 4px; + position: relative; +} +.card .alert.alert-with-icon { + padding-left: 65px; +} + +.card-user .image { + height: 110px; +} +.card-user .image-plain { + height: 0; + margin-top: 110px; +} +.card-user .author { + text-align: center; + text-transform: none; + margin-top: -70px; +} +.card-user .avatar { + width: 124px; + height: 124px; + border: 5px solid #FFFFFF; + position: relative; + margin-bottom: 15px; +} +.card-user .avatar.border-gray { + border-color: #EEEEEE; +} +.card-user .title { + line-height: 24px; +} +.card-user .content { + min-height: 240px; +} + +.card-user .footer, +.card-price .footer { + padding: 5px 15px 10px; +} +.card-user hr, +.card-price hr { + margin: 5px 15px; +} + +.card-plain { + background-color: transparent; + box-shadow: none; + border-radius: 0; +} +.card-plain .image { + border-radius: 4px; +} + +.ct-label { + fill: rgba(0, 0, 0, 0.4); + color: rgba(0, 0, 0, 0.4); + font-size: 1.3rem; + line-height: 1; +} + +.ct-chart-line .ct-label, +.ct-chart-bar .ct-label { + display: block; + display: -webkit-box; + display: -moz-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; +} + +.ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-label.ct-vertical.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-label.ct-vertical.ct-end { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + text-align: center; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start { + -webkit-box-align: flex-end; + -webkit-align-items: flex-end; + -ms-flex-align: flex-end; + align-items: flex-end; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end { + -webkit-box-align: flex-start; + -webkit-align-items: flex-start; + -ms-flex-align: flex-start; + align-items: flex-start; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: start; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-end; + -webkit-justify-content: flex-end; + -ms-flex-pack: flex-end; + justify-content: flex-end; + text-align: right; + text-anchor: end; +} + +.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end { + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: flex-start; + -webkit-justify-content: flex-start; + -ms-flex-pack: flex-start; + justify-content: flex-start; + text-align: left; + text-anchor: end; +} + +.ct-grid { + stroke: rgba(0, 0, 0, 0.2); + stroke-width: 1px; + stroke-dasharray: 2px; +} + +.ct-point { + stroke-width: 8px; + stroke-linecap: round; +} + +.ct-line { + fill: none; + stroke-width: 3px; +} + +.ct-area { + stroke: none; + fill-opacity: 0.8; +} + +.ct-bar { + fill: none; + stroke-width: 10px; +} + +.ct-slice-donut { + fill: none; + stroke-width: 60px; +} + +.ct-series-a .ct-point, .ct-series-a .ct-line, .ct-series-a .ct-bar, .ct-series-a .ct-slice-donut { + stroke: #1DC7EA; +} +.ct-series-a .ct-slice-pie, .ct-series-a .ct-area { + fill: #1DC7EA; +} + +.ct-series-b .ct-point, .ct-series-b .ct-line, .ct-series-b .ct-bar, .ct-series-b .ct-slice-donut { + stroke: #FB404B; +} +.ct-series-b .ct-slice-pie, .ct-series-b .ct-area { + fill: #FB404B; +} + +.ct-series-c .ct-point, .ct-series-c .ct-line, .ct-series-c .ct-bar, .ct-series-c .ct-slice-donut { + stroke: #FFA534; +} +.ct-series-c .ct-slice-pie, .ct-series-c .ct-area { + fill: #FFA534; +} + +.ct-series-d .ct-point, .ct-series-d .ct-line, .ct-series-d .ct-bar, .ct-series-d .ct-slice-donut { + stroke: #9368E9; +} +.ct-series-d .ct-slice-pie, .ct-series-d .ct-area { + fill: #9368E9; +} + +.ct-series-e .ct-point, .ct-series-e .ct-line, .ct-series-e .ct-bar, .ct-series-e .ct-slice-donut { + stroke: #87CB16; +} +.ct-series-e .ct-slice-pie, .ct-series-e .ct-area { + fill: #87CB16; +} + +.ct-series-f .ct-point, .ct-series-f .ct-line, .ct-series-f .ct-bar, .ct-series-f .ct-slice-donut { + stroke: #1F77D0; +} +.ct-series-f .ct-slice-pie, .ct-series-f .ct-area { + fill: #1F77D0; +} + +.ct-series-g .ct-point, .ct-series-g .ct-line, .ct-series-g .ct-bar, .ct-series-g .ct-slice-donut { + stroke: #5e5e5e; +} +.ct-series-g .ct-slice-pie, .ct-series-g .ct-area { + fill: #5e5e5e; +} + +.ct-series-h .ct-point, .ct-series-h .ct-line, .ct-series-h .ct-bar, .ct-series-h .ct-slice-donut { + stroke: #dd4b39; +} +.ct-series-h .ct-slice-pie, .ct-series-h .ct-area { + fill: #dd4b39; +} + +.ct-series-i .ct-point, .ct-series-i .ct-line, .ct-series-i .ct-bar, .ct-series-i .ct-slice-donut { + stroke: #35465c; +} +.ct-series-i .ct-slice-pie, .ct-series-i .ct-area { + fill: #35465c; +} + +.ct-series-j .ct-point, .ct-series-j .ct-line, .ct-series-j .ct-bar, .ct-series-j .ct-slice-donut { + stroke: #e52d27; +} +.ct-series-j .ct-slice-pie, .ct-series-j .ct-area { + fill: #e52d27; +} + +.ct-series-k .ct-point, .ct-series-k .ct-line, .ct-series-k .ct-bar, .ct-series-k .ct-slice-donut { + stroke: #55acee; +} +.ct-series-k .ct-slice-pie, .ct-series-k .ct-area { + fill: #55acee; +} + +.ct-series-l .ct-point, .ct-series-l .ct-line, .ct-series-l .ct-bar, .ct-series-l .ct-slice-donut { + stroke: #cc2127; +} +.ct-series-l .ct-slice-pie, .ct-series-l .ct-area { + fill: #cc2127; +} + +.ct-series-m .ct-point, .ct-series-m .ct-line, .ct-series-m .ct-bar, .ct-series-m .ct-slice-donut { + stroke: #1769ff; +} +.ct-series-m .ct-slice-pie, .ct-series-m .ct-area { + fill: #1769ff; +} + +.ct-series-n .ct-point, .ct-series-n .ct-line, .ct-series-n .ct-bar, .ct-series-n .ct-slice-donut { + stroke: #6188e2; +} +.ct-series-n .ct-slice-pie, .ct-series-n .ct-area { + fill: #6188e2; +} + +.ct-series-o .ct-point, .ct-series-o .ct-line, .ct-series-o .ct-bar, .ct-series-o .ct-slice-donut { + stroke: #a748ca; +} +.ct-series-o .ct-slice-pie, .ct-series-o .ct-area { + fill: #a748ca; +} + +.ct-square { + display: block; + position: relative; + width: 100%; +} +.ct-square:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 100%; +} +.ct-square:after { + content: ""; + display: table; + clear: both; +} +.ct-square > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-second { + display: block; + position: relative; + width: 100%; +} +.ct-minor-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 93.75%; +} +.ct-minor-second:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-second { + display: block; + position: relative; + width: 100%; +} +.ct-major-second:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 88.88889%; +} +.ct-major-second:after { + content: ""; + display: table; + clear: both; +} +.ct-major-second > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-third { + display: block; + position: relative; + width: 100%; +} +.ct-minor-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 83.33333%; +} +.ct-minor-third:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-third { + display: block; + position: relative; + width: 100%; +} +.ct-major-third:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 80%; +} +.ct-major-third:after { + content: ""; + display: table; + clear: both; +} +.ct-major-third > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fourth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fourth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 75%; +} +.ct-perfect-fourth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fourth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-perfect-fifth { + display: block; + position: relative; + width: 100%; +} +.ct-perfect-fifth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 66.66667%; +} +.ct-perfect-fifth:after { + content: ""; + display: table; + clear: both; +} +.ct-perfect-fifth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-minor-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 62.5%; +} +.ct-minor-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-golden-section { + display: block; + position: relative; + width: 100%; +} +.ct-golden-section:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 61.8047%; +} +.ct-golden-section:after { + content: ""; + display: table; + clear: both; +} +.ct-golden-section > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-sixth { + display: block; + position: relative; + width: 100%; +} +.ct-major-sixth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 60%; +} +.ct-major-sixth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-sixth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-minor-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-minor-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 56.25%; +} +.ct-minor-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-minor-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-seventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-seventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 53.33333%; +} +.ct-major-seventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-seventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-octave { + display: block; + position: relative; + width: 100%; +} +.ct-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 50%; +} +.ct-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-tenth { + display: block; + position: relative; + width: 100%; +} +.ct-major-tenth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 40%; +} +.ct-major-tenth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-tenth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-eleventh { + display: block; + position: relative; + width: 100%; +} +.ct-major-eleventh:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 37.5%; +} +.ct-major-eleventh:after { + content: ""; + display: table; + clear: both; +} +.ct-major-eleventh > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-major-twelfth { + display: block; + position: relative; + width: 100%; +} +.ct-major-twelfth:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 33.33333%; +} +.ct-major-twelfth:after { + content: ""; + display: table; + clear: both; +} +.ct-major-twelfth > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +.ct-double-octave { + display: block; + position: relative; + width: 100%; +} +.ct-double-octave:before { + display: block; + float: left; + content: ""; + width: 0; + height: 0; + padding-bottom: 25%; +} +.ct-double-octave:after { + content: ""; + display: table; + clear: both; +} +.ct-double-octave > svg { + display: block; + position: absolute; + top: 0; + left: 0; +} + +@media (min-width: 992px) { + .navbar-form { + margin-top: 21px; + margin-bottom: 21px; + padding-left: 5px; + padding-right: 5px; + } + + .navbar-nav > li > .dropdown-menu, .dropdown .dropdown-menu { + -webkit-transform: scale(0); + -moz-transform: scale(0); + -o-transform: scale(0); + -ms-transform: scale(0); + transform: scale(0); + -webkit-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -moz-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -o-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + -ms-transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + transition: all 370ms cubic-bezier(0.34, 1.61, 0.7, 1); + } + + .navbar-nav > li.open > .dropdown-menu, .dropdown.open .dropdown-menu { + -webkit-transform: scale(1); + -moz-transform: scale(1); + -o-transform: scale(1); + -ms-transform: scale(1); + transform: scale(1); + -webkit-transform-origin: 29px -50px; + -moz-transform-origin: 29px -50px; + -o-transform-origin: 29px -50px; + -ms-transform-origin: 29px -50px; + transform-origin: 29px -50px; + } + + .navbar-nav > li > .dropdown-menu:before { + border-bottom: 11px solid rgba(0, 0, 0, 0.2); + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -11px; + } + + .navbar-nav > li > .dropdown-menu:after { + border-bottom: 11px solid #FFFFFF; + border-left: 11px solid transparent; + border-right: 11px solid transparent; + content: ""; + display: inline-block; + position: absolute; + left: 12px; + top: -10px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:before { + left: auto; + right: 12px; + } + + .navbar-nav.navbar-right > li > .dropdown-menu:after { + left: auto; + right: 12px; + } + + .footer:not(.footer-big) nav > ul li:first-child { + margin-left: 0; + } + + body > .navbar-collapse.collapse { + display: none !important; + } + + .card form [class*="col-"] { + padding: 6px; + } + .card form [class*="col-"]:first-child { + padding-left: 15px; + } + .card form [class*="col-"]:last-child { + padding-right: 15px; + } +} +/* Changes for small display */ +@media (max-width: 991px) { + .sidebar { + display: none; + } + + .main-panel { + width: 100%; + } + + .navbar-transparent { + padding-top: 15px; + background-color: rgba(0, 0, 0, 0.45); + } + + body { + position: relative; + } + + .wrapper { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + left: 0; + background-color: white; + } + + .navbar .container { + left: 0; + width: 100%; + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + position: relative; + } + + .navbar .navbar-collapse.collapse, + .navbar .navbar-collapse.collapse.in, + .navbar .navbar-collapse.collapsing { + display: none !important; + } + + .navbar-nav > li { + float: none; + position: relative; + display: block; + } + + body > .navbar-collapse { + position: fixed; + display: block; + top: 0; + height: 100%; + width: 250px; + right: 0; + z-index: 1032; + visibility: visible; + background-color: #999; + overflow-y: visible; + border-top: none; + text-align: left; + padding: 0; + -webkit-transform: translate3d(250px, 0, 0); + -moz-transform: translate3d(250px, 0, 0); + -o-transform: translate3d(250px, 0, 0); + -ms-transform: translate3d(250px, 0, 0); + transform: translate3d(250px, 0, 0); + -webkit-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -moz-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -o-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + -ms-transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + transition: all 0.33s cubic-bezier(0.685, 0.0473, 0.346, 1); + } + body > .navbar-collapse > ul { + position: relative; + z-index: 4; + overflow-y: scroll; + height: calc(100vh - 61px); + width: 100%; + } + body > .navbar-collapse .nav > li > a { + padding: 30px 25px; + } + body > .navbar-collapse::before { + top: 0; + left: 0; + height: 100%; + width: 100%; + position: absolute; + background-color: #282828; + display: block; + content: ""; + z-index: 1; + } + body > .navbar-collapse .logo { + position: relative; + z-index: 4; + } + + .nav-open .navbar-collapse { + -webkit-transform: translate3d(0px, 0, 0); + -moz-transform: translate3d(0px, 0, 0); + -o-transform: translate3d(0px, 0, 0); + -ms-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); + } + + .nav-open .navbar .container { + left: -250px; + } + + .nav-open .wrapper { + left: 0; + -webkit-transform: translate3d(-250px, 0, 0); + -moz-transform: translate3d(-250px, 0, 0); + -o-transform: translate3d(-250px, 0, 0); + -ms-transform: translate3d(-250px, 0, 0); + transform: translate3d(-250px, 0, 0); + } + + .navbar-toggle .icon-bar { + display: block; + position: relative; + background: #fff; + width: 24px; + height: 2px; + border-radius: 1px; + margin: 0 auto; + } + + .navbar-header .navbar-toggle { + margin: 10px 15px 10px 0; + width: 40px; + height: 40px; + } + + .bar1, + .bar2, + .bar3 { + outline: 1px solid transparent; + } + + .bar1 { + top: 0px; + -webkit-animation: topbar-back 500ms linear 0s; + -moz-animation: topbar-back 500ms linear 0s; + animation: topbar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .bar2 { + opacity: 1; + } + + .bar3 { + bottom: 0px; + -webkit-animation: bottombar-back 500ms linear 0s; + -moz-animation: bottombar-back 500ms linear 0s; + animation: bottombar-back 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar1 { + top: 6px; + -webkit-animation: topbar-x 500ms linear 0s; + -moz-animation: topbar-x 500ms linear 0s; + animation: topbar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + .toggled .bar2 { + opacity: 0; + } + + .toggled .bar3 { + bottom: 6px; + -webkit-animation: bottombar-x 500ms linear 0s; + -moz-animation: bottombar-x 500ms linear 0s; + animation: bottombar-x 500ms 0s; + -webkit-animation-fill-mode: forwards; + -moz-animation-fill-mode: forwards; + animation-fill-mode: forwards; + } + + @keyframes topbar-x { + 0% { + top: 0px; + transform: rotate(0deg); + } + 45% { + top: 6px; + transform: rotate(145deg); + } + 75% { + transform: rotate(130deg); + } + 100% { + transform: rotate(135deg); + } + } + @-webkit-keyframes topbar-x { + 0% { + top: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + top: 6px; + -webkit-transform: rotate(145deg); + } + 75% { + -webkit-transform: rotate(130deg); + } + 100% { + -webkit-transform: rotate(135deg); + } + } + @-moz-keyframes topbar-x { + 0% { + top: 0px; + -moz-transform: rotate(0deg); + } + 45% { + top: 6px; + -moz-transform: rotate(145deg); + } + 75% { + -moz-transform: rotate(130deg); + } + 100% { + -moz-transform: rotate(135deg); + } + } + @keyframes topbar-back { + 0% { + top: 6px; + transform: rotate(135deg); + } + 45% { + transform: rotate(-10deg); + } + 75% { + transform: rotate(5deg); + } + 100% { + top: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes topbar-back { + 0% { + top: 6px; + -webkit-transform: rotate(135deg); + } + 45% { + -webkit-transform: rotate(-10deg); + } + 75% { + -webkit-transform: rotate(5deg); + } + 100% { + top: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes topbar-back { + 0% { + top: 6px; + -moz-transform: rotate(135deg); + } + 45% { + -moz-transform: rotate(-10deg); + } + 75% { + -moz-transform: rotate(5deg); + } + 100% { + top: 0px; + -moz-transform: rotate(0); + } + } + @keyframes bottombar-x { + 0% { + bottom: 0px; + transform: rotate(0deg); + } + 45% { + bottom: 6px; + transform: rotate(-145deg); + } + 75% { + transform: rotate(-130deg); + } + 100% { + transform: rotate(-135deg); + } + } + @-webkit-keyframes bottombar-x { + 0% { + bottom: 0px; + -webkit-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -webkit-transform: rotate(-145deg); + } + 75% { + -webkit-transform: rotate(-130deg); + } + 100% { + -webkit-transform: rotate(-135deg); + } + } + @-moz-keyframes bottombar-x { + 0% { + bottom: 0px; + -moz-transform: rotate(0deg); + } + 45% { + bottom: 6px; + -moz-transform: rotate(-145deg); + } + 75% { + -moz-transform: rotate(-130deg); + } + 100% { + -moz-transform: rotate(-135deg); + } + } + @keyframes bottombar-back { + 0% { + bottom: 6px; + transform: rotate(-135deg); + } + 45% { + transform: rotate(10deg); + } + 75% { + transform: rotate(-5deg); + } + 100% { + bottom: 0px; + transform: rotate(0); + } + } + @-webkit-keyframes bottombar-back { + 0% { + bottom: 6px; + -webkit-transform: rotate(-135deg); + } + 45% { + -webkit-transform: rotate(10deg); + } + 75% { + -webkit-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -webkit-transform: rotate(0); + } + } + @-moz-keyframes bottombar-back { + 0% { + bottom: 6px; + -moz-transform: rotate(-135deg); + } + 45% { + -moz-transform: rotate(10deg); + } + 75% { + -moz-transform: rotate(-5deg); + } + 100% { + bottom: 0px; + -moz-transform: rotate(0); + } + } + @-webkit-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @-moz-keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + @keyframes fadeIn { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } + } + .dropdown-menu .divider { + background-color: rgba(229, 229, 229, 0.15); + } + + .navbar-nav { + margin: 1px 0; + } + .navbar-nav .open .dropdown-menu > li > a { + padding: 15px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:first-child > a { + padding: 5px 15px 5px 50px; + } + .navbar-nav .open .dropdown-menu > li:last-child > a { + padding: 15px 15px 25px 50px; + } + + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .active > a, + [class*="navbar-"] .navbar-nav .active > a:hover, + [class*="navbar-"] .navbar-nav .active > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus, + [class*="navbar-"] .navbar-nav .navbar-nav .open .dropdown-menu > li > a:active { + color: white; + } + [class*="navbar-"] .navbar-nav > li > a, + [class*="navbar-"] .navbar-nav > li > a:hover, + [class*="navbar-"] .navbar-nav > li > a:focus, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:hover, + [class*="navbar-"] .navbar-nav .open .dropdown-menu > li > a:focus { + opacity: .7; + background: transparent; + } + [class*="navbar-"] .navbar-nav.navbar-nav .open .dropdown-menu > li > a:active { + opacity: 1; + } + [class*="navbar-"] .navbar-nav .dropdown > a:hover .caret { + border-bottom-color: #777; + border-top-color: #777; + } + [class*="navbar-"] .navbar-nav .dropdown > a:active .caret { + border-bottom-color: white; + border-top-color: white; + } + + .dropdown-menu { + display: none; + } + + .navbar-fixed-top { + -webkit-backface-visibility: hidden; + } + + #bodyClick { + height: 100%; + width: 100%; + position: fixed; + opacity: 0; + top: 0; + left: auto; + right: 250px; + content: ""; + z-index: 9999; + overflow-x: hidden; + } + + .social-line .btn { + margin: 0 0 10px 0; + } + + .subscribe-line .form-control { + margin: 0 0 10px 0; + } + + .social-line.pull-right { + float: none; + } + + .footer nav.pull-left { + float: none !important; + } + + .footer:not(.footer-big) nav > ul li { + float: none; + } + + .social-area.pull-right { + float: none !important; + } + + .form-control + .form-control-feedback { + margin-top: -8px; + } + + .navbar-toggle:hover, .navbar-toggle:focus { + background-color: transparent !important; + } + + .btn.dropdown-toggle { + margin-bottom: 0; + } + + .media-post .author { + width: 20%; + float: none !important; + display: block; + margin: 0 auto 10px; + } + + .media-post .media-body { + width: 100%; + } + + .navbar-collapse.collapse { + height: 100% !important; + } + + .navbar-collapse.collapse.in { + display: block; + } + + .navbar-header .collapse, .navbar-toggle { + display: block !important; + } + + .navbar-header { + float: none; + } + + .navbar-nav .open .dropdown-menu { + position: static; + float: none; + width: auto; + margin-top: 0; + background-color: transparent; + border: 0; + -webkit-box-shadow: none; + box-shadow: none; + } + + .navbar-collapse .nav p { + font-size: 14px; + margin: 0; + } + .navbar-collapse [class^="pe-7s-"] { + float: left; + font-size: 20px; + margin-right: 10px; + } +} +@media (min-width: 992px) { + .table-full-width { + margin-left: -15px; + margin-right: -15px; + } + + .table-responsive { + overflow: visible; + } +} +@media (max-width: 991px) { + .table-responsive { + width: 100%; + margin-bottom: 15px; + overflow-x: scroll; + overflow-y: hidden; + -ms-overflow-style: -ms-autohiding-scrollbar; + -webkit-overflow-scrolling: touch; + } +} diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/pe-icon-7-stroke.css b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/pe-icon-7-stroke.css new file mode 100644 index 0000000..44bcbaa --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/css/pe-icon-7-stroke.css @@ -0,0 +1,632 @@ +@font-face { + font-family: 'Pe-icon-7-stroke'; + src:url('../fonts/Pe-icon-7-stroke.eot?d7yf1v'); + src:url('../fonts/Pe-icon-7-stroke.eot?#iefixd7yf1v') format('embedded-opentype'), + url('../fonts/Pe-icon-7-stroke.woff?d7yf1v') format('woff'), + url('../fonts/Pe-icon-7-stroke.ttf?d7yf1v') format('truetype'), + url('../fonts/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke') format('svg'); + font-weight: normal; + font-style: normal; +} + +[class^="pe-7s-"], [class*=" pe-7s-"] { + display: inline-block; + font-family: 'Pe-icon-7-stroke'; + speak: none; + font-style: normal; + font-weight: normal; + font-variant: normal; + text-transform: none; + line-height: 1; + + /* Better Font Rendering =========== */ + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.pe-7s-album:before { + content: "\e6aa"; +} +.pe-7s-arc:before { + content: "\e6ab"; +} +.pe-7s-back-2:before { + content: "\e6ac"; +} +.pe-7s-bandaid:before { + content: "\e6ad"; +} +.pe-7s-car:before { + content: "\e6ae"; +} +.pe-7s-diamond:before { + content: "\e6af"; +} +.pe-7s-door-lock:before { + content: "\e6b0"; +} +.pe-7s-eyedropper:before { + content: "\e6b1"; +} +.pe-7s-female:before { + content: "\e6b2"; +} +.pe-7s-gym:before { + content: "\e6b3"; +} +.pe-7s-hammer:before { + content: "\e6b4"; +} +.pe-7s-headphones:before { + content: "\e6b5"; +} +.pe-7s-helm:before { + content: "\e6b6"; +} +.pe-7s-hourglass:before { + content: "\e6b7"; +} +.pe-7s-leaf:before { + content: "\e6b8"; +} +.pe-7s-magic-wand:before { + content: "\e6b9"; +} +.pe-7s-male:before { + content: "\e6ba"; +} +.pe-7s-map-2:before { + content: "\e6bb"; +} +.pe-7s-next-2:before { + content: "\e6bc"; +} +.pe-7s-paint-bucket:before { + content: "\e6bd"; +} +.pe-7s-pendrive:before { + content: "\e6be"; +} +.pe-7s-photo:before { + content: "\e6bf"; +} +.pe-7s-piggy:before { + content: "\e6c0"; +} +.pe-7s-plugin:before { + content: "\e6c1"; +} +.pe-7s-refresh-2:before { + content: "\e6c2"; +} +.pe-7s-rocket:before { + content: "\e6c3"; +} +.pe-7s-settings:before { + content: "\e6c4"; +} +.pe-7s-shield:before { + content: "\e6c5"; +} +.pe-7s-smile:before { + content: "\e6c6"; +} +.pe-7s-usb:before { + content: "\e6c7"; +} +.pe-7s-vector:before { + content: "\e6c8"; +} +.pe-7s-wine:before { + content: "\e6c9"; +} +.pe-7s-cloud-upload:before { + content: "\e68a"; +} +.pe-7s-cash:before { + content: "\e68c"; +} +.pe-7s-close:before { + content: "\e680"; +} +.pe-7s-bluetooth:before { + content: "\e68d"; +} +.pe-7s-cloud-download:before { + content: "\e68b"; +} +.pe-7s-way:before { + content: "\e68e"; +} +.pe-7s-close-circle:before { + content: "\e681"; +} +.pe-7s-id:before { + content: "\e68f"; +} +.pe-7s-angle-up:before { + content: "\e682"; +} +.pe-7s-wristwatch:before { + content: "\e690"; +} +.pe-7s-angle-up-circle:before { + content: "\e683"; +} +.pe-7s-world:before { + content: "\e691"; +} +.pe-7s-angle-right:before { + content: "\e684"; +} +.pe-7s-volume:before { + content: "\e692"; +} +.pe-7s-angle-right-circle:before { + content: "\e685"; +} +.pe-7s-users:before { + content: "\e693"; +} +.pe-7s-angle-left:before { + content: "\e686"; +} +.pe-7s-user-female:before { + content: "\e694"; +} +.pe-7s-angle-left-circle:before { + content: "\e687"; +} +.pe-7s-up-arrow:before { + content: "\e695"; +} +.pe-7s-angle-down:before { + content: "\e688"; +} +.pe-7s-switch:before { + content: "\e696"; +} +.pe-7s-angle-down-circle:before { + content: "\e689"; +} +.pe-7s-scissors:before { + content: "\e697"; +} +.pe-7s-wallet:before { + content: "\e600"; +} +.pe-7s-safe:before { + content: "\e698"; +} +.pe-7s-volume2:before { + content: "\e601"; +} +.pe-7s-volume1:before { + content: "\e602"; +} +.pe-7s-voicemail:before { + content: "\e603"; +} +.pe-7s-video:before { + content: "\e604"; +} +.pe-7s-user:before { + content: "\e605"; +} +.pe-7s-upload:before { + content: "\e606"; +} +.pe-7s-unlock:before { + content: "\e607"; +} +.pe-7s-umbrella:before { + content: "\e608"; +} +.pe-7s-trash:before { + content: "\e609"; +} +.pe-7s-tools:before { + content: "\e60a"; +} +.pe-7s-timer:before { + content: "\e60b"; +} +.pe-7s-ticket:before { + content: "\e60c"; +} +.pe-7s-target:before { + content: "\e60d"; +} +.pe-7s-sun:before { + content: "\e60e"; +} +.pe-7s-study:before { + content: "\e60f"; +} +.pe-7s-stopwatch:before { + content: "\e610"; +} +.pe-7s-star:before { + content: "\e611"; +} +.pe-7s-speaker:before { + content: "\e612"; +} +.pe-7s-signal:before { + content: "\e613"; +} +.pe-7s-shuffle:before { + content: "\e614"; +} +.pe-7s-shopbag:before { + content: "\e615"; +} +.pe-7s-share:before { + content: "\e616"; +} +.pe-7s-server:before { + content: "\e617"; +} +.pe-7s-search:before { + content: "\e618"; +} +.pe-7s-film:before { + content: "\e6a5"; +} +.pe-7s-science:before { + content: "\e619"; +} +.pe-7s-disk:before { + content: "\e6a6"; +} +.pe-7s-ribbon:before { + content: "\e61a"; +} +.pe-7s-repeat:before { + content: "\e61b"; +} +.pe-7s-refresh:before { + content: "\e61c"; +} +.pe-7s-add-user:before { + content: "\e6a9"; +} +.pe-7s-refresh-cloud:before { + content: "\e61d"; +} +.pe-7s-paperclip:before { + content: "\e69c"; +} +.pe-7s-radio:before { + content: "\e61e"; +} +.pe-7s-note2:before { + content: "\e69d"; +} +.pe-7s-print:before { + content: "\e61f"; +} +.pe-7s-network:before { + content: "\e69e"; +} +.pe-7s-prev:before { + content: "\e620"; +} +.pe-7s-mute:before { + content: "\e69f"; +} +.pe-7s-power:before { + content: "\e621"; +} +.pe-7s-medal:before { + content: "\e6a0"; +} +.pe-7s-portfolio:before { + content: "\e622"; +} +.pe-7s-like2:before { + content: "\e6a1"; +} +.pe-7s-plus:before { + content: "\e623"; +} +.pe-7s-left-arrow:before { + content: "\e6a2"; +} +.pe-7s-play:before { + content: "\e624"; +} +.pe-7s-key:before { + content: "\e6a3"; +} +.pe-7s-plane:before { + content: "\e625"; +} +.pe-7s-joy:before { + content: "\e6a4"; +} +.pe-7s-photo-gallery:before { + content: "\e626"; +} +.pe-7s-pin:before { + content: "\e69b"; +} +.pe-7s-phone:before { + content: "\e627"; +} +.pe-7s-plug:before { + content: "\e69a"; +} +.pe-7s-pen:before { + content: "\e628"; +} +.pe-7s-right-arrow:before { + content: "\e699"; +} +.pe-7s-paper-plane:before { + content: "\e629"; +} +.pe-7s-delete-user:before { + content: "\e6a7"; +} +.pe-7s-paint:before { + content: "\e62a"; +} +.pe-7s-bottom-arrow:before { + content: "\e6a8"; +} +.pe-7s-notebook:before { + content: "\e62b"; +} +.pe-7s-note:before { + content: "\e62c"; +} +.pe-7s-next:before { + content: "\e62d"; +} +.pe-7s-news-paper:before { + content: "\e62e"; +} +.pe-7s-musiclist:before { + content: "\e62f"; +} +.pe-7s-music:before { + content: "\e630"; +} +.pe-7s-mouse:before { + content: "\e631"; +} +.pe-7s-more:before { + content: "\e632"; +} +.pe-7s-moon:before { + content: "\e633"; +} +.pe-7s-monitor:before { + content: "\e634"; +} +.pe-7s-micro:before { + content: "\e635"; +} +.pe-7s-menu:before { + content: "\e636"; +} +.pe-7s-map:before { + content: "\e637"; +} +.pe-7s-map-marker:before { + content: "\e638"; +} +.pe-7s-mail:before { + content: "\e639"; +} +.pe-7s-mail-open:before { + content: "\e63a"; +} +.pe-7s-mail-open-file:before { + content: "\e63b"; +} +.pe-7s-magnet:before { + content: "\e63c"; +} +.pe-7s-loop:before { + content: "\e63d"; +} +.pe-7s-look:before { + content: "\e63e"; +} +.pe-7s-lock:before { + content: "\e63f"; +} +.pe-7s-lintern:before { + content: "\e640"; +} +.pe-7s-link:before { + content: "\e641"; +} +.pe-7s-like:before { + content: "\e642"; +} +.pe-7s-light:before { + content: "\e643"; +} +.pe-7s-less:before { + content: "\e644"; +} +.pe-7s-keypad:before { + content: "\e645"; +} +.pe-7s-junk:before { + content: "\e646"; +} +.pe-7s-info:before { + content: "\e647"; +} +.pe-7s-home:before { + content: "\e648"; +} +.pe-7s-help2:before { + content: "\e649"; +} +.pe-7s-help1:before { + content: "\e64a"; +} +.pe-7s-graph3:before { + content: "\e64b"; +} +.pe-7s-graph2:before { + content: "\e64c"; +} +.pe-7s-graph1:before { + content: "\e64d"; +} +.pe-7s-graph:before { + content: "\e64e"; +} +.pe-7s-global:before { + content: "\e64f"; +} +.pe-7s-gleam:before { + content: "\e650"; +} +.pe-7s-glasses:before { + content: "\e651"; +} +.pe-7s-gift:before { + content: "\e652"; +} +.pe-7s-folder:before { + content: "\e653"; +} +.pe-7s-flag:before { + content: "\e654"; +} +.pe-7s-filter:before { + content: "\e655"; +} +.pe-7s-file:before { + content: "\e656"; +} +.pe-7s-expand1:before { + content: "\e657"; +} +.pe-7s-exapnd2:before { + content: "\e658"; +} +.pe-7s-edit:before { + content: "\e659"; +} +.pe-7s-drop:before { + content: "\e65a"; +} +.pe-7s-drawer:before { + content: "\e65b"; +} +.pe-7s-download:before { + content: "\e65c"; +} +.pe-7s-display2:before { + content: "\e65d"; +} +.pe-7s-display1:before { + content: "\e65e"; +} +.pe-7s-diskette:before { + content: "\e65f"; +} +.pe-7s-date:before { + content: "\e660"; +} +.pe-7s-cup:before { + content: "\e661"; +} +.pe-7s-culture:before { + content: "\e662"; +} +.pe-7s-crop:before { + content: "\e663"; +} +.pe-7s-credit:before { + content: "\e664"; +} +.pe-7s-copy-file:before { + content: "\e665"; +} +.pe-7s-config:before { + content: "\e666"; +} +.pe-7s-compass:before { + content: "\e667"; +} +.pe-7s-comment:before { + content: "\e668"; +} +.pe-7s-coffee:before { + content: "\e669"; +} +.pe-7s-cloud:before { + content: "\e66a"; +} +.pe-7s-clock:before { + content: "\e66b"; +} +.pe-7s-check:before { + content: "\e66c"; +} +.pe-7s-chat:before { + content: "\e66d"; +} +.pe-7s-cart:before { + content: "\e66e"; +} +.pe-7s-camera:before { + content: "\e66f"; +} +.pe-7s-call:before { + content: "\e670"; +} +.pe-7s-calculator:before { + content: "\e671"; +} +.pe-7s-browser:before { + content: "\e672"; +} +.pe-7s-box2:before { + content: "\e673"; +} +.pe-7s-box1:before { + content: "\e674"; +} +.pe-7s-bookmarks:before { + content: "\e675"; +} +.pe-7s-bicycle:before { + content: "\e676"; +} +.pe-7s-bell:before { + content: "\e677"; +} +.pe-7s-battery:before { + content: "\e678"; +} +.pe-7s-ball:before { + content: "\e679"; +} +.pe-7s-back:before { + content: "\e67a"; +} +.pe-7s-attention:before { + content: "\e67b"; +} +.pe-7s-anchor:before { + content: "\e67c"; +} +.pe-7s-albums:before { + content: "\e67d"; +} +.pe-7s-alarm:before { + content: "\e67e"; +} +.pe-7s-airplay:before { + content: "\e67f"; +} diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.eot new file mode 100644 index 0000000000000000000000000000000000000000..6f7b58489c6fe76af1597fad93bd8ebe36114eb9 GIT binary patch literal 58680 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 Nxi7{(cl`%H{|#3vvLpZi literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg new file mode 100644 index 0000000..13d9709 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.svg @@ -0,0 +1,212 @@ + + + +Generated by IcoMoon + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.ttf new file mode 100644 index 0000000000000000000000000000000000000000..bc8a269c68dafaaf5aaa7920e7a17baff0748360 GIT binary patch literal 58480 zcmd443w#_`eJ?&|cV}kjwY#%#?L*S;N?Kczt;cG;j^B>uM`Alph^0J8OkS2l^NO{q+C2cP;OpnK^T2=FB<2$M^R*5|bp!kS3*|)W7A*zQJ($)%Re}QT)H*<~wfO znHxFLE=jC_?M*vweEUxP#;|=We#1L%f5+I@j;ugkhW+3Bw_CU0cuQcd_Ov9ucngj% zx)nQuKMp*B?LWkJ$E|nVHSsPZ|88u5Rg!{>Zy&$;#{97#-6Tn;UqKt6xZ}o&ozhR) z*CgqOe}MY!ciwo%_Ipko#`!<|GLC<2=lI+2!hPcN!ST4``m-5%>f`Mx3blQJnq)n)x|TQA*C(sN zULvG!;*Z|YWSELM)k%duFibz0AuW-b!RnPx^ew4`BRJ7XA0&1h4j zS~#w0@vs(Eb;VNEXgC~IRZG$D^WIHZ4X1D`*>E`Qy+&+gaU&@l#AGH4aR-ROmC~TJ zQ3CB_zD~do$v#SJ>}oyJOLKSXGnOK`W`M;dnIG zoy~SfWAS(_+MQ)Nuk73(v#gF}suHoHQ7ckOB|9uD#@;z=2d~7gPqws$on^bEGAP*+^piS+b`_bJl%ivnvrMgCQIiTN zTi0?nvU@b8}ywfJF%}RTu@63FsGiYbZ_sXQs&~UT%@T3SJtZCy=UW=;>V zP%xmdU^ozD0mcFWMGxt!8aHh-uBv*_kg<>969}q7rUYoi$XRAuF^F)tw&aGZ?^RQn ze7X@tTOqU(Ks9O#ZHGgeB3o)KY$;$78t4Hv2C9HsGAOe8vNyJ)c| zX5BNtdz)X%E=8jS6Z8e#i3L@~l;wCh6tzs;XE1B3#YhO8NMTF?FA7D9s+kQk*)XkW zC>$qp6%MeV76P3z3$Z9TCUuANY)}mmyNiXDSXhpQ8T!IBHM&VAw;G|e5kmh283REJ zhm3T{XhpZ+IW^Nndn^pX7}eBRh}uzue9B_>CM+6n0cqsiPuXF1A0&&UBy~2bYNlb= zY_(ni%dVtq_+}f;tFAIHjt`Bqq47!Q(35=A`4x*i9VadsXKS5jL|ak-Z9OYhq!CK~LE6XmnmCGcOvAFJq%a73Vk``q@~b zY!Lym%87EBALF&gUV7;}$BvP-bncg+gD-$*LE>ZeO3EF7=}g0S3#poKqdDmXF|1&^ z(`=^+19?SEEr0b?ttqrrGn~qbnIZ`5oMk>gL~9wr)|eKrU0W_y8M8IK1Kr>Rl!&RJ zCqULQ_^mLc6IroMEo|}wMnY9J+pR-I#;T?AwY4wejIb$(a6&?xUA97ezfPRRkc0Eu z+qd@hZEbI#7nBX+IP9rhE-=4bd2+zGj&LP(h6yf zv>tqHTC(gB?2JZAEy0P%QYPM3qE@dCEy5P)a;2U~4I~v*?y3*egSB9=W>;*3sfk22 zm|+J;l#pzyqbmAI8HwAVxR&~iYJuw7_9-0)^ohed_UQIGdmPckW@VP8}<|SoOCzn`E$}q%!?`} zS+&s=g^7YL>gr=rwvq%N{JDb)V^~RNP?M%)24l>>zYSzJr3&gT*n()Mikhg+Df0Aw zns^Kcs);6PCPAv3Radf#3VJTcI3M?D7kA*_lc5_+lY}n*Fi-lJnvu~0mFQYT=-EHM z*)%(rZNSjNSPe%N-2zck(tTD$nV0=On3P)5O`-8GP zueEBR?sRp{1X&AhSl(fp*K$G#@ zPgsRU@I;_l2hX8`?zgbTEg+FWO_fdBrAAfxi2zHHilBwA?YNfoh2d-QM9Vkewm_~G zJ!_eH%jjaQ^FYnPC&b>gX|`A!+^4yOs)jUG%UTxd&TFg6cvwc92RqZI)nZ;EoQm6J)!7n-Jrvq+~*dt7A*nAL`4Pc z2?m~!x6^&o?Q5j;aGKnd>vPgpXny_af#$%YQPJO3sdkm|V)5R)G0`y9>U`|D!k$kE zbmecs&Syv>KW8CyHtARpeAumEu;5Uarvjk>i&uwRa>etc+DusUNwr+Q{T2%;Tt$P3 z6xf0{ss?xbSi62C(4Nb$tNLX0svU2On9*4>I+xb@e9N8tH9G@sUXd)R3(^$m3Cpm0 zm1a^clX@*J6ayM83-mh0et(zae4PcZ+3?Fh`{hlS?*>^jRnQRraZ5EwBAETE&c5cH z`vzlgyXM$0j{IWFE!$?*6X)`px=J)b!Cl$Vr@tU&U2XaU(q~^w((}Cqmo*7Vz3!9u zXS|U)RmujJ;RGRZ1v8KfKefm-Ty?GFXN7*vfU!u6rsJcvL{QQULqkb$5Xfd2z{E?4 zxfKQz@pL+#7%UV9f+DDzuu9Rji6tfMR9a zq*!629LwX1&TcMcajD2FfxOW5BP}}JiSFLhgr zu~=_Qwl_xi738W_2|8kax&SQ?OKcBUCgzt z?egvlD2;UPG~|)f{QWMHmI4h}3)Ex_X5cmdC+|5}OI7MNeO2kJL|;VC8;r=kJzZi_ zexV&tCgb+Pe6CNF`f{GU)u6GX7H~vhvjep;OR{C=Jg>gHX zwBv4jXYE*1IBSY&F`JF=*x`(gjeRPP&k<|AxxslKHOB7QV6L~E_fd1uYr;~Vy}~{X z)GsEb(F@>eAT}9Dfek)46Qw$!686d~uT<g+uvTX zeaGbF4(Gtrmt6+9FDNa8{BR8N!#rsYI24>~Mm6|JG&68- zLgHilBGGtvJQ^`EBujR#YfVc_!J}vZn-b=}&ebj1LLu9-y3;FZaUu`=i*0q=Fl@{X zRxStI^SQM?s+Q=C*{u=hZ)P>Y8~eu2ok56rR$C8IVn z)kX#UR&DgLS|d|aGi=eKMPK~Dq7UHji+1(SJ9~_qAL{OY=*|#JeD2Su5Wjm$)f zq?-NScfI>-_VDmmZyMV%CjZQgX2Y7MV;0A(Sb<23rsZM{Q?mj3DXL-{rb#pfT^%=A ze)oTQBY?EXri65zFjIrw8)+!Bn~fFjF;?sTaTEkx!4LPH;-j$)`tB zkC}$i8n^7CZs4OAZ7bet80KCZ^fPbfx}#CsjzoKMR=zhHvxlL$b)~Iz#j+x}a0SIq zsB@UV-BKs}4*R%dN^z-(zRy&ukU(hQHmWj84X|t~tCbf<}@gd|Ps$5@6!TjF?h zr$BwUO0k>)^GVhGQcrVNjU8~t*j|E|os&(f7mY(l_9?A3n>~SA2b|rgHT6%0@7%$+H3y5E0AbB9G zpPjoZchH9wLC67hbXD`Jf5Ts?bFKsIAm{lk@HbGT0AqTxfErO1L!RWa@hssW98sWz zPI6h8vA>p~*ZR*K@kX>KMx6DEUWpBRWv|4Z<>OV>Lt9B7mc6TUwD!hojxh(|W0411n^PAU=V+v!b_ zrY`NDO^_Wr=M;ILzl#fhxpaDIsk}6uZfQZO94T5>R=+FdyeFMZ)>~VLlF3XanH*|u zttXS|-n*bOTE&Q0zl1Y$T!6eQ^*vr^)_D?aN9!TedaKcWc%Lik%1nrMcuii0=>rwcsK zZBg8T3s&&v1XYvE5EU&e4hb@yq+F5eYvD!;JHx5Z(9CBP#YP77VUTeR$Jzv3Pi z_wPT@;O&T+EIQ4*RRA$;Z!E1SK&``&YfLf%#WV%z3E=7^OhXDV5!i&RxB^%hh(pja zLWbfy1;-GA0Y0R==NJ#M5j4x8 z8W;pL1EhQ&SP!9!jGmLDAN-Dj0Tryrl;4RqR7n2;hy6(qs1Yi|_8|j83j~!Q-V5(JdKF@i zzm9lb>JagV9_77*X7H{8LEOC@Y#|IRgtvirqk!#U@5SQPi0{j=8_$jUsEC88(u(?M zf^JZk(FFD`gP{fJ8<02@fd1m|bB3-LRQ|5$g1Ct;5Qk6)qmuXQnw3JwhGflXGut=rBsa_asFU~dEIr;c_(amC)_GF zoGE*kDD58=zX#A>?cC3R{rtT&Us{0neB9d=$x@A~&<*^|sa^?Y)H*xr!5&oVI(V@A z(iv7X`}5=DPt5`)Mz&o)0)XYx9uLxB@~YLp3)xtbRzTOg4=B_f(j&MVkZvD91j6h= z&LGu7WSL<;PLYum1X|qt%0QEr0#0leL5Ney{(%DAL1utgGeplh9$NGcUTG>G?=O&o z(*is8?Cu3F{o<|Ui&{xyg~zCRuZG>iI#?t?1C1Z&d8pt4qgg*>)<7k!wz0xB_Ryn*yIN9lnq4~ zZyd5DhD1fh|LN_9@{<5jV5s#!SFJnP7Ldp;~q zR+aJQ>323O-`U*LXx5qQ_ZZj_-85K_=hFc5O_1CfUh5dU3?mcgDQuW`h4ZSfTflU{ zKb$kXJ9uX~uYS1M5oYt|%;uh~=qee8O1F(?o{r}$%OTNcunCkQ z_n(5?Z(_a=LUUP$nJy*#<8;PMfps0`nzBN6?4^w0xxq#7R)O;!akvCL&Qc9t1qSvB zB5(vo)`YQHk!Y~BO`L?Tu2@sc7KMQiT(SB z$HvZ{1$_!hwsbZ8YiB3HgYstZOhQ&X~9 zz46+Fp$78dw~VH$qY6o!A=Oq!zMuZ$cEt|7Sy69E&y(etJTlr_-4cQfO}dAcfTyW^ z`KjJ7Y*CV-t5OdpuTe$?=Zq`C%~lGCsVpZ)k{p4WtWhxHmy7q3S5JPw=v{k+!#Nxq*8^lnb;~a1KM14oS&# zzhM8&{uX2SccgLYF7yDrAiBy?rX&Tc#hYZ%-^DW!4$!X*;7yj3zz7EV2VGPP0|M|w z21ZB@KR_JkL!?oMx6Z)OV0~~AJasT0T!r3sPJpcpei39b`{&_U7PjU0k^dKz8+L!( z`CbB=v;yr?C&iRL2~u((q_uOGtbm+mtDO&XZyl{_c0nb=AmJ6^WV$e0zKM1q4~+w@n? z=*Q*VY~2g%mwxMGkL_oNj<2|5}k+9+KPO#ow42s1)n zgpUm$R!xto26wvwJ#jt2d)NRl4)T-)AM)!696=8fCxUQ^7wYN?RFhs%(@C6t75qG^ zIsXCx15Vyh)A`3z9}Vl}kuo;SaO(Z4VUTwe01}n}I3mOS=0L5smrEedzxZT`1eZS8 z`*XY&Z#t)t*UwUN;Zc~OEpW3r9ma6e zmSBVOFW}U8#*C|BI;*KFD1HUp7p5{>^dQ_#`4cC6x>60Zo=Hl}nF0M>P(nhhfAvSu}y?R(Ww4jz&*#OPTW%IjQLpcEEnDI`7lZ*B5==ITHX> zAin}znG$xU;J5{k;ut*1V8O#XUIrcF7<7mvEG-N1j`>WB5*fl><9*OO4}vDCFuSA@ zDlE*+Nkr%~J1S(Gjc{%nj%}ju+3cKp^?}Mmt6wnwmUMPLcLMB>KoUY5Bj9KDCUJ`M zAy$5{^C5>_{Y~oyF`TLP1?2|l>!9muz2W}aXV2P4kDkK!GtaPFonK5%6(Kehn*~IJ zO!LP)H0mYNN_ehcB3&k32^k_)=})=?atW*9&lTrm1EruKgnU@`FjosNal%n2I!r7) zHT~5fw;1$DEwyh<*WhfYjSSUqPU~@i&Cb!jaO(&LDUdsM6Ad)Qd70eH1FU>bI@SE( zDcDnI-_`;+kA!zMj#u|qXNQ^C^LCt}Xk~>4XGkY$8u1JV$jR)CZ7;+3pEz89ev@Sf@fpazfJI%pi+f3C9aO}4$+ zwm%qcp9hs#!BB=BMN{G9r6;4YO6-4ztksICY1z2*_d%kBtpFF{Ib;Df6h2F^*`50j z$XL(Ab7Cu}M{^JVn}Xxc7hp|>{TfCG6TmJ1Bn=k!%HDDI{4M{X5P|nj=OvcA z`X|^Q47vMpF;mm?QDR3`XXUK6d3)OcL+}f#8kJzu4y!;5LeeDSiYDQEGJxJ&D~)h! zPSgi~%VA>@?>GW9hQI$NQFpDNV(5_EDn#!JCtM9|3zVCr2i`)3X$c*GCFpQU2TU!i zaOa67xYG!CJ%KAtPYaw&2q8JeQJS%F?tgNM+fdn6IVB4C7*MO)-3?rpFibQ>rW&NPR{^A=0N)9wC2BY`#&&?H+YSj&)%5;ybl8aWKi-@<<6=;SJMN= z^l|ST@3?o)iCH#DZl}DEBN~I3@%bi9B4Fn^xQ+b(P?P8wVX7ilssmn8Qi2ae|2y&< zP6Tyoh+Y3lr2$Bxkf-3ab!oSmHO;gE)h|;k%)ca`Z-eJSXS%PlES1idi^VMqy4Ds7 z)v$?}osL8mK0U3F-oR`>sHZ7br~8sZz8%7vCTF@p#@h4w4c+;{G#nSYw0Zf$aOZ+8 z#ny65CcV7Ff@6kSY-t(pN+9&7XyN(F;I*f~YfWgzQYRP+SP2)HL?j$Lz7M-`UAi7E_-Cgeg3Wmw6p{ru)nT8fDI<)< zovEAv@~KalR)%YXkljRl5ca#aSP#bJe)gL^n3Ch904#Ougg3u!^6M+I&4)Gxisa^J z@8KQ}hsaYOULNq&Kg9hW5PpC&K}7+29`eA=Ln9-eZ`sI5aVU|@1V(IoB#=oahKe9t z!cTGw_`ohuHR5+Px8Ws{fXi4(roaLI)qo&XS80=%{O%gNsdsJi$grnNY}fE`tz4eu z-v{|OT}#H8w1KgH0a|^W>-8nBp$tIVgbe{!glZ54J5#kYc4NB4b{XMqW8>pvW8=4+ z9vOj8(hmO34#}au+G6Lx;-R6%Y^>%y(al!%IRCA?o2~9~zKS2;7F|DtIE>SXojC3K z3cM9p_xWQ$ujL%j6(m!BVA4;1fNM_EqD&rIv@6(w;tkA6@&*u2x;T|=fpQX-A9#Sz zp_XK7ak~eNd!@>XY$gx2PLn_K5w0)hGuaiDSz(tv0F%9tO`#DTVrnA%(o5llt|fI` zD3v`)xHpBd0TuEw@9b8TOn4O*q;~WgmuI0>mit&qhS7w3!$b6gdRc<&eTp4(cCbUX{b?npe433p zd&kGEJNsmqlOl58oz92Zz2oB~YO~VBpTvJMYyVmF3U< zFUH5>%{+Jo8&BX`_4u!n)xV*Ry{kmtSyeLABM3l35eAg#a zpsT`*!|y9n@l)Ix9X2PqedA{^sj{lIZAG~V@2j;vJ(sq(*VE}m?d_L#cddYHeXi}I zLgAve&Wnphgf0vgix+osv71ZXUWo>+g;+!}d_~El>t5-Cw0uuGnYgH<71TS|24B&1 zzLCxpol~hqVxUkOM9@^0bj5UkGTHL-tn2bScxKjx`OWO(_Eqo7ytKoM-uFrv{Uh+D zqu9cP8(rwPR2L!8!z7QOuxZc&yXtT$M|9!1_u3Irxa@>CIF7y|q6@u|i-J^)}@u^bwP^&Vx&MhM=Q<+XLgPwTu_aJH4LJ@WY(g=A+&-OLp zA%fO1-U)pNm52(Z5k_C42~-IJ37x{LOfwCxanUK$HdHWQbO-(_tOY(EP#jG?W0_g) zHh@`>5Fo5)wN2(G1LAnA0XJ>ayp23OV(MOAT^75{)@ZENOqxmm$syOd2o6G_4dw=7 zpt117B%%OjfGg@siThfT;V-ib1NQUI+5RC&F* zo}VK6uml<4lZY|83{-h;SxtD+2~1i{ef2yF-E^05$MgW(#wQJ4ys3WramBz}<&!E_ zgeSZLHN`B($mt~&hARU6XLu+LhK3n_@=pekdRKF*iN2`=+l}{3Z@jO@ zUoY_VUtMqCe|3Yex4r*s7ryUx<8f^F>#n-gi|WBSNJv0|lB2V5NRBfud);mR-@ZKM zN;oe{g@-%XpDX&f26&Q> z2!?6Eh7q34}Z6X{1_V{Q#V;4{=8lY%1$ zT47^`DcHP{so@_(Au6&J#Q|MKZUS9qJLO;UCeRB0j@V^bv*CgJ1eYF+6eL04oFjo0?)zjg-fh zna@9Oo*XWhhYuXzz5Doq1JCT<{p8-gPf`ZArVTmEV=J$dCZva?gVLW$FGzrvULRM7 zsD)AHYV9k9oGrFgp`p4`Q$t9aB-*2Xrs@iw1N^1ARb6G4VlhZUcjFY?O@X(&0ky6~ zmvLKj+jci=i`f7lFAdR<;3~*n!NUvQa3oconki z$hy)4i8gG>m-N6fUC|Z%q0plvi3$?-K!i=|PxmNrw+jbX0U%Ig+M3nyW#^w@V3pT& zcopT_G30Iyfw`7)NiUQM@{s2t3q3j@NaS}&1CrFg(oN!|7FE>n_Q09#0(>ciF=|_VLts_U2RLF7eb~5lNY(w15g6HQ^ zWF?|OQirktut|v-I);L-(Ljl4JfG5EGzER?O9nn6{Iw}!0G@&FKadq7AOnCZ*s&3N zB#!?!JM`-lY`3$Qoa4sE_V2e(LDp~5h!Ct1h?VCtt1>`YGDeiZNr*VvCD+ukYx78L zkc=Glp^?pZz@3msqS}`pTs~1=!d5y{ZOhB|EdL|t7j$p3lmagNb70qRlin{qCjG_i z9Ag>i_GDth#C2bhkHmXfX#AGACbenh9u}DY7dq&hz+S0PHM2EWbAe6l#T3;8Oa!cK%)`5e3P5WBfb?7K@k%*q$q zOXJIaY`^Mc;`&3B#o5IP#|FOqb{Rk zC)@ML9T!LXwR}70^RZ$ylCzX>qTNKu)uF;rCS5j;aG?PiI)s)8l(qvTh@G;QC7kh=U;frhw8d~u08PAkMXpU z)%|OLG^uttyC9jYSg`drb@XmXhwJg|w}89lTdHR-$3%iussR%Mif5D(7( zggv*}EB#`p;H6C(DHyAG`byo6@^!lf!9vtoE}sRMB5)U8xuyyuugkGT_lqluvt1ru zgY%D&351a`BV1}kn@D2HCzX2!Y$1ZA3lOVO36?d5&lTEw_Q(j2t}AC=tSXViO@Jm7ZGGu!a;Vuy%{wTSxKWNKxG84@n}unE=n+L zVDBdQ>d=`~zJA+uyWuEBZ<6;WlLOe8Zg*Q31P*e12~%XFg+!qcG7u$?`A2berm6$l zYl&gBMqGL7~33cgSV3jLV~zESar;d8OMJktp_NWDP+R!sV%nI*YdXO0ukhZ zi2ED1i-^9(TkA?M5f zYDfu*7%#UP#SBt46_KH!M*(RJ*!=-u_mmF`vOUb1l}002Qxla2>rLPIDg0$m?aJei zJ$B^ek(0}uQ>R!NvN-s#B;5@g(MDKI$0X#Z?)2N%RPMYiW`USIn8}!2OZ~VvMIJXY z6!1(EyK7N$r5)Kv<%AUOO7x|<4zPcf1BpnaBZYLdRx*?YC(4GB7V_1mIwFxoKm@CZ zD&!Xx%jII^CFMKn>_u7>GlC?t?TL8Fq>@>Rv#?k8j{ggH;J~0kst?9^iVurBc~Ha) zKgNBqFvKk6dSl!ZYx?+(sA(b-OS?&_FJ7xeKAbh!c22;yGaot;`83`N`STu$qSpjP z@uAIv()fvHhKF8o6E0M?S~Y|B>lXw3y{Y;vL~d`3!=%HL4ZFspH+YsC_Ev67C^3jhT zIr7|*BWxXIWQ>G)su$?$l4@N6?u_~OpCni?C1Fv&#F3v(jCqrWJ;R=-f)ZN!QajquY8vKwP_@% z=a5}-nR8NCPn=M7n!{2D=I|eazrLB~aKGZJm(AH1Wj3X2a&=k3`^e*i02lnts!co3 zuT5%6iXAX}I&>swwnd6&y|ayl;&LuaJIG0&OekFonGz30;KFM8tAgf0ESOc-%)m)o zW*-Y7mo3;1q)-+xSkQUoQ%IBN+Y>nPmzYPyCQyaf0)-6(4pA-ILp%-tg6t5{w5ER< zr)h`;1A>&Q*6NKCkcryZVRrQJ$S|Ur4-`K0!ykUe{`fb(@p19~Z$o_aM-d;b0Ed91 z1gp~28NiIG2jQYdF-jlZx1V+I+qG+I_de$pR@jH6HrhLO?Q%ZICiaS0ucmGiMhiK@ zOA-VJ!7~IdEtISWWsac083FmIkhuptDn};mJ?5TQZ^oDH{Bn;ydGnrMp?veC&Hj)! zu$wB}Jn6hjJNMj4dnR$yp3gn`fW_hCBLPRNr1)g*q!L}T6W4$jJF?Z*4j;Dn?qxN5 z>h^b=?{bd9`|Ie5#NopS_U^4s+3z;rebb4f+#L*UE5NxD@QJ6q_Ctt#c&jue{V{sQ zM{QhT3GkF4MCW^6xKxBe$>U?qPw8DjXwH*FwlNGx_cC}2AHA#2c^*54um(y=54T%j zdzLD4m3DiPn4S>toD>IVoiQVeJ%o9Z=ao;vX`|_c>MLqK>3>?UVfT4T5M|R>1I~-A z5+KuAI5$fj!udfNK3x^(MNwh)sl!4YnW;&g`Q6_YwMFwYx2Df<^(cOec&7nr8}!?Q z&~MA|bt2sZxZQxNB+pkqF7S35uroF?{YhcPY`)sxXTO)6U_8ktPy50Xx&Uto%fH`R zhuzBE3h<#}-~1++ zuZD^|dknYp35;2RXG%BGXcc$?kjM;j6i?GK%q@^&zncyw1e-X!jUBrFr$5+ypXXR{ z-(`rnn|MbsqU%t9U}cO1-@$f`9X&c`kC6Qs4tTI3kDQYZP+EENB~Mugs2@k9<*@nw zJ-9QX)e@Lwz#b~_wx^8Hn0NSos+ktrIX*tg;Jd}QS;YC()3yT{%66V%h+)ON%}MQu zeR~u>dMT9Kz<rnvtG0%mG;#Gt?(ji?5XxPWR>sgw0s#AB%B?TL6f z@S!u#Q27}w(=hc+xkmmFC&tE*Q*LNC|8P8oFctQw?VRYb?H#r|7?Ya$K@D3^r$WrToG}0mrR%0~ zE_m%QT)xDEfcg6;j*UMI3fxI0MfO?Z0%{FRdxq%Dg}LPv=HSWOt`_Zg45nOeQ{%bZ zWG;7yFtG$n@#rn2S1n#=MOg@Gb;zd-bP>7*3@M>FP@tGj+6M~om~cThB%+&QIp+-9 zmc!?F!<0gXMc(pYa9$|bW^Z5!D<^wD8W!1Yq1^Da5Qt=h&l_TaC=Vg!gEKHco`Uqd z3gZqQ->koku)0z=6IeYSr;XM5GeOR!K5!XD%0p6Rpa4L}YJ>f?fm%xT5et&m;J`^o z;G=;9;CXDod4dx9ka0-f$n&BO9~kBdQ8&^qFcs(UN+^%84-GQg^ZRDfsJ{WBeKYUJtSxB<)yc6#AL=tBG$1C7;Hv!w;6Ywv~Kpw!{2f@R|sk;%O%cG}* z7?$*(?Q1hzou9#Z6GU!!xZwPnDZgg2^P8(#s?}<()#A?ghlXqxbAHQ0@FWg7zol!a zc+czbp7%hCDY-GbtGO?(2oszse>W3z$VBY$I=QV7Z?cnKGGZqoi^K8ErHwLlN{ap` zNuHd}YV3qF<_Q7pfLC_FBb-q}1y$WhWTkP4Z{^C}ay!EOTE1ZA%_~uG8HH0V2v})Z2`2*r?;8Nlg;OibI$%SBDQXn| z0Wo(ht5Agy8|b5Iau8<#*+Ph5&ny>DE}gK)=7&fl!p*jJv>EVkL>rcSv$BDkRRGB0 zae{q){Hc)m3OlJHp2r-r=;FZ0+d5kLQ=zf>&e>Tv&mV}D7XT?i{;Kw6B{CKo3htP^ z1v{2?P=ACNCNjSh>>zJKJQ6CQYH3+JPQ%FyoU@)t<&}7h3gpcbkT<&_Z(b+eC~b!x zLAZs>cBZW-d?1|9m#QK$ohxhlU-z6QbfoQ%(paW+zbb2o>^*JLP~^^)@Ei9sUBI(^ zWoNrLf4!2Iu-Yq)z3<}pufDYBP1VJ{Z|Y)G05-j#3!te=M=rm%tH(__b!ku6+I+4< zStNw_X|n;pgfr}U$9ts_H2-_Md#hKr_jbJr^r4145hsu*q79{0K-sQE&k0)Sdd@Co zfMWPGBkG0;NqLHTDE+XAI2VL)M%JJiSyBWf=K^lXu5ic`r+%@f;%#8TnW3Kl;G_#H zLcpOy*z<;)g@>92_Ar>Esh;AjZFrb7z*A^PhJK^!y}ddP;p9`3O@rXb5ReO~RE1)lJkhAiMX^aFWZ}9=`;v4jAE?z1BE4iH z!^&JAImm{cqX@17dxqTm*xpI5!DK1KXJW^Wa}wfw>#gJC{FJiI4sON=v71Cs1Nbj; zge{fs#M^Oc(E0hidhp^rtIY*6fld3q3hYi$U-xNer!XJ_mB&$4^Ht`uP+ zn;6@5p_E*&k-^JGaPDj8|AN}b6NRDAJR2_A(~;5U^?7#qNjzi^u!IY{On6h)D~;_& z5@K)Wd!-BK%|C1dO5$=))9+`1JeuD4eI^JAhlWjFPnc;d*`guZ@%lYYZ`<1+qGj4H zVxYA$`!K|Atk(2KZ1u4R`ay(@&_$5G10O&kMA*OQGiySsgG|RTy&z#=eJ^yZj17n) zNHYz&17QLq&UYsNblB*gbY5cN{o`z^yYX41Q>#y&L9F1Jkz?Z{lZ^(V0Z7J31F!xk z;MD@Fri>XS(pb-rWF;m53z>gXyL@2)$$}dGfXx|}ZDC^*xaEuk_;AAUE0Tkb&)yU(NlD%Jk-MTjTh zQ1pN*Xhbu7VkRI>@e>?_CSbZj8W7>rZKMbm*&7eW7If(XZ)i>zWOiiTeE58;Bj}NN z8(bX<+ic7$gP}MFh!bqdC87U}z!h)dWvYJ63pMddp4XFCx{xGxK`Cm>d_*S7$WR2X zbb>P?UlGtdFmzSV1yV3r1QudLgx}-hG22_r!50(bxh);OkSw*=6MnoB<^<)n{5AU< z@U%^oNmAIhga9qZuNx&IVK(O_*t+#(~g)a0=|bAv)aESzTAxrq0TRG(>wKnIz54lue6q;8gOg^nM8b z#uhc{?R2ZSJNLef(5T}tzU*ONz9Qz>%QV38^)m9cLKWx#Yxt%AyM5bi1&{PzChSr^ zDbTf7IaAaSHt_8nI$9gHNAQ1iXsvx1zrM}A2W(Em1kd#FD~d}e%u0r`?xI(uw<8Zw zrOqL&9r}#&2#UT0j~Bjnb$A;{_fc!4#_meb*Iqk0U8mwvUP zMpP>rZdF#b@iD|UdCU=uyLEwZW5qBA14l0U$15IK|0#YL=>utPHgP>l-;2E7ZSg>0Y6#e@k+HlrC;8oW-OKYPQ6E1Pz#3Mv3dJNL^8tDqqJTZ=zvbsCm zGOl6{nkW4Jrjx{_xO~R7_a-e7PoWC`GIzvCkX1G1XW9j(jl0mYJ7fII45TU?vT)t#L{NFNw(9qygC)uH z;j7mK&dr}@;hcGiuEU*)avSUU{M?@`mOCG`_CM~!uzzTVT3FIHN z3Ije;N#C*`Nrzt7DdGJL%QIKf7gorQr+QM!YTT?OQ~kMT0M{v@#QapcH18YiU6NM}g#%0g#|bAN-ByWlXVRs;q$8fw!? zQS^BIjNQAorKL^H4z=W9x%$K>AVst-Efj{bdOCg07Ix!0mP{s>&MUO3YGCcoouz&I zMz9cXe^24^&aOpl6k|OHd*B(^11YC1<>ZxEuoO%sN(td1G}CYW3_E`2dFRgOwRl`> z<|1Z~J3HBj%Fd_Q^^?1I?}GszZ%Ky1Cm^*$Rz3|`c?EGS#1Lg%_ej^vKpI*_IAH9d*v~so^t6((I zfdo}1NDFCN4nuE8Dt}yfhfP!+Q`k3$36tFd>2(a=?h`ZT@H7%X-H~FRy6X9y;A>D2 zI*1aDI&!9Pf3l_UVTM(*xxjH|pbGJVR2z_RF55DR!!#HIw$W?#SVbF2rxG18tS8-# zl?4%ft#XjGLf|bywiTrRprv?_7G!gc=Ss-#w8!`hET5|F#8RY4<1jpiuwgKq6Weyi z*?qJMVbv}pfxJ~WhG@Yw`XtODV-c+;UAC*VR-to%=NjQ@b*R+A^Ng_lyg@Wi0YU?XJ6i z%KG;rRVNYv!x9GzljIzpni^ZS>=Xq&L5i7VH?q~R|B;sgx2=-}@4uP%iv_6Kl_EFW2V_U@;(=e<#MrbS?>b)PNP)ZykOpjT)wR> zpW84GUh-7Rub*$4H=1;HV>)(@>R#5%-K^RER;n{^Lq69Ae|T|T>%Qgt!o zJLS*E4$OKk{;d1l`#9}6jZ;ZH;jE|PPulDaJl9|1xfY1$YT&9gMo+kp^Uu?db^dd? zQjm|B3xZRhbA8oj>+IyL*To;v8RM^M)~oxldk6f%d@qc@M0&ZcvtC?tw9%ZV@%YCW zj}dxjB*fG7_&2x3C*1MC=l-mB_QtW|s@pn~yiw?lOm7r=k7tSN53nzJ!_XU==#A-N z=sh95WeLT3_$-EWuRVy#C$E@0FU^A0-K z?Bz`$mbmX(T;!`JEl6lD{!ua>AIK*=qOmN69Kb!4uVkWYVkMLDaZc>v*_+1VB}|9^ zJF=Ky@e(y1vD)lxcQoc-ykuem>k+w2s=a7!+GIAq|NX{W$qX@I^Yu#dHnMY*gO{8z zt+p6XFoi|epyyaQ9jlZeiY z(vAP}{!9UKARa38g4zAaR%5A0>d>2LX&7`U-9I`MDLAM@bIA1)qbyurho&sJ;3608 z`5lS~pXn5Z6BAwn!%I!{=;G6-7r**n+M~LK9z}jcu2s_f)A4^bVvyg%>HH#ir49pi zyFwa;xAP5{p6AmJF{b7OsH+4*aU?3mU08raHGdfaQZRy4>R$3TW_hw19NoEJc^pYy z1xSO`=*^Pyb@s4x2fGj6z`HJSz7%60j$P{fxy>H7ou3cl!z}(yT1T8RfQgo{^eReQ zInW`Z(SiI3-=I(a<~NIvd~e>jfBsv${PW+$m>G+G*0w*(zlldk$b%VR--o0TBUvL; zC$9{QH;{c~r9&!X{NFuh-oDGc?fvh#`yqSVwwrEh`F2$~{cN7TyH>l~ ze&msR1_$rK&m%0<(E(;H0Z{5mzmMtll?};s4`uOAb#O$r}dj_|5 zci$b0JqXd1d}1Q(N%%Sm+>lm}C_&5Yk-mkuJpE$0(U$;IFRpv@+{%e6GCGUh_12^2?7u z{`mLGW&F?(IuoMR?%-O6#TY`gE*Wqbe2`Guju}xK!HQxByhCuD$_l`;NJx=w!o$P1 zVnDCN*>FT5KqnBwUY#N|$Vna_azg1NN|li0p@Q8lq5=cV%Y0YM+=Zc zN|c;t$RP!>SAmd@;ZOK1bR_oY>?lf|Kxdcm%;r!wxB${*TGan4{F~D5DhWL7sM=fz zyAkYbuED4_&X=QveD!yB-R%F#?rX59TI*0EkqNLBE!&2%EMIXbnMl87_gglGY+7h} z{RcPnnltmPZ6SV8WFx4dOj zyv+g{vEF%meDi=^G!0v>UkpVN%`Ax9iG&?rKn=#B3=$3aCEEplL$dxm!NKQ}6X%Ti zNs!DTP*1-U$psxh7@BcoAZM%}QR9kt17U|HD`y_&OdHKgwBf}OgZAn17jZB6J{^uGle8%iN&m@bbudO(8veUmpg8kl2 zn>OBf<0Ciy?6S-5xqPL4&prTQJPiY-nAP96EV>#E6yS zSWrAUFP^AG8%A&vs*c@?bw& zZD0wknOL@D_BIcMrwPiLICRr#I!+@D^JkMGSZ`HcXNcg$p>Fbn2u-b)X3BWT3>a}TRGu=2n?nR&-h@qsG1Dsg7>_%J! z{adMH*)(NCT19@GfU2w4Li`Kr;rz8KjH0@NRKqO>u?e`lg0vHh0P~QIAbhjphK;2o zRSg05oD0FrdcvY zP!pKTao~WDz#jwYja!hHLNrMfUN9)sgk2Y_kcQC?U_mSmN_RyUfNdD-bfTRQOd1II zRYC#hM-QTPxQr*lG&67<|J~ZSs*2PUiW!M=xRtjdDxeK485_2;K>F{Vlv|KTQXyUg zQ(T*>L=dh_DNTYZvZ^8qIvB+w%y^by##D9%_>>~&kLx^#G0YFB$ieMPz?X?psA!8 zeqbxd%5OI1EI{f#7^)3ZqsTX=6!lPArwojA1Js(H4(UZOPaIV=(_rXggdat8H3l0v zHG>89y1UcpAi4y2a}2AyDnSHRhgeus@qG9wElMy3<33~r*!JacEU0E-k;f%eEsQ29 z^@53|bzw2b@~6R26l=i-THX1cVGm1)OV(xGT=gx6q1mHZo3aJldW1t@{{(J)RX zJXS(M9u>vNU6hNYp)4SY{+cez#b1QZnz7jD+6wtgy1OsQ7uvj%^C@z1#vFx|q{<~s z)Bv)9f{v%HtVk%HwbDe{Gtl?2ZgMNHNK=X?W^-{N&D0YCtPX~E4iW*{Uovg1E{-)p zje?DcXuBP{Hx7m%lqEE*>S=c+yVd|e1P` zV!?H#t4f!{&-sVBKFYmHN~AUNuYde?gni(57GSU|a9@g2?tBCBMd*O24jVYUm*x#) zfu10YzFFwz{0QbFuZ7uk8J``Y0z!K**&z@viVViqJ_{c8Y_XP3cSM{QR09);6fI;t zK^b#{RIylC5kFyl_Tf~m_VvL*=U?GnfBE3xvw;ZPvhiXN16)*35DN(L8$cOqTyP1f zGy+(~9gF({cfsAm(hHl0l{R9~u9R?GM>2@ZW3e4sa35wvFEhf!@S#9%tgsH|ij3gX zWqHhhqy7iDKIVS-7?7kk%;7(VRh!n`Tn$eW!e3yU6V#oIIDEX%fb`tND{#8tRNX%n zgrgJ1q1BM52?0YC*)qU*5u5hF-_asM7K_Ijmf1i?jVAsSrB#D;wqyx|cO4e>L4YQ$ zO`I|xrQ5YhOJ&w?e+zx}G3PpH((h*Xv0fs}QQ%+1UkyDUi{-Jn@k88%7vm_5uEN|0 z??F|M*Va5VxaJ<`hpg54*WdmY*`d$^RN)((M=wCj8l2I%GuhAQ=Cn5mT?>!>cOEtJ z=-Dh9#_5`6jExyreB&FDSu~8F&mNvd#W-bie!^*4jOH)N-(mIz_GPRjb1m}iNS!J| z<{;h@w*|w*#3F+!=A>9C64N3NLL2wn}7p{Cqp+zGID5h zH_3?z%M1kn0qsVM5onc|O0{_;%#-bdNv-TDc2If%y&)#DNUuol?5+aa90YxA0NsK= zPt$6;t4^=>flkACax;Lsk{VZ~xT+%t7W$R{iGe3h^;#_>3#$hGKaF)$)F04Gc+9FcK=BT&8LVGK#~Zv)QrFmN7$jkd!# z0&Dm+rcqIjStoe!H-%jgQV?3MunOV}*C;WN1w~%Tcot4(^Y}dY;K#@q z5Yv$X9fR`^*u#HtCC5fM>`iXC;G};90TV!=_FdYyEi?)>3jJ9mk&K;KltF!AAIoH z?%ZcTo9o7Z{C@ADhnx>Qgb(#G(aKi#0LFR>>(*2;_>pnVg?C`ltRWj)3jbw-cc4qu z0QJDHW}vRJ2h6wKd&A1x%zIeuX8YaFmq%{7cg54A=G$%di1D`T0khm@+!MQn+3)$) z-IuR4_guEdy!M9Mxi1DVrE~udCI1_^-fB?jw<8~#JI|)WwEZBQpTk!1wn%!K)?wTi zkNG!e&c8SA&HvpHa_s2e1r`tqCE7qiJpmEQKzsa?SK3=!Vpu&GQWO$#L6EZY*LhN_ zSE4LSw0cWND%FV?%sacnQnmjsuSLN3i^gjw4#GhhzJ>8W2d(Ka@ z(su*oCENc+eQWu5aEN4stRpaXYh+V|u znjyH;6R|>OWcuN8{awW{ArIID2GN3KY$W0m9+3%n#4k0D*niMYJEL9-Lj-{^Xczno zN^$^@M!KNvSf-nhV#D$ou40C416Tz{0~|8dl+9bCdkfn9hC~sYph;Ne4uBG9zp5Ps=|N7gu6VqFXEaLPYspd( zCZ(6=JN=)bpU#O_%Ro>F!E;&C=b~-4&9~+SS<% zYtjKCgandK0v*s0NMvyUWhBaYh&XddW)$RbPzWd@-~=+GaxkJ2LM&ZF&+pz>UDctZqkqjzow`+Tx$nLE-n;jAf9v-L6~NVZu<)%KCs*U{lr(yhgj$s~ zjfbaW>JVtBil&OG(*o@|!qm~`6Tf%7j;+p(&0{t6LS_M-)>M-KJ#nTX4%h(g_-VYc zQfZ%jt3llLQ-j@~$rANmoMn5m8T{DdDxhzDF4x^92H?=y=1jb@`a_Wn*s`&3WLA=7 z8DY=?1DS~N7b7G6a!^9jWMlwfi!^wDxGr#y=0Bc64Rl#E zE?Vg<3T7opYLNv4pF-DVj1^F&RtFoa_PI4LQjlHsPfSmx^ zsnH~}Y&77DqP%lP30L#`D1~68GK6JGP4(iCJo1Nj8c7Zb zIjv|OG&~sl_H=RvBAOK;(}!U>VGjb?Ty|}L5vkY{#~&V(Am13~4mKo;{cG8M0~*0y<|BFNqz z?GJs@9kj_Fse$!fY#jGs8b^!AegLL!ODWNK=`ma)UojP zD8XFb!46CnV)XH*dclL_+lx4w@=6+ekn048O8+u%+M+dQ<;zx5HnX4^Rz0njbOIe< zawRejlM?yuWq|8n32M>fR4yt5S)W=-z`nMm(2!)W{L0yc&+2XKlWJ`s=#l+Kgf)Kq z5ZS=g>o#Or(nhNZ855QI;@KmP1)PAkDMDkzxywE2rcc^rr$mjasW|9)&M?&6kuPO3?GeTQh}F`m^rE2fHqG)HF*b{hKz-!T>D=ma zLpvH{;#L5h1Ul*U@NB@YvczR%Gu5=009JX#n3>D6**4K`&p|_s5=>5}SS~7Y(0l}* ztymF^_3BX3lF5a{h{Ohd<%CGr`1b+~ED(NpEHI}Bz3arf;4)Nm2veDlQk^p^WsU@L z3how48By>&hF>u0EhVXaZD|C?0i=r>s)8&P;X&2Z8;e9cv)nq$QJSL-$ZAJpCcO-v z(J85;rETh$A2FujhoEj=%r>;yISjC>(iLe_j%%I5iNm}R zRPA8|aeaf}2;b6cd;*%Y!|`SDj}a}Y`sz7Kx}&m{3f?gbYFBMSV^E~pWW?#wA*&~O zzA$_0=~8U8YDC#KS>kPUZ&zJik5C+9xIp_5elo~ITyA<3XkV&7*_Xnc!w{R^2)YE3 z3w8>I3a{ANIQf}btQ7Ef7%E`uvjNK{#;Wrh z(RyO*JRjRuFo2=Z>Gq~Dcn0y1k!X6cV5zssFD#_s^MR}zmOS%svpAw=2?g;jPr+iY zoNdmoe%~i{LM{#*A5buVf}zkI^23KR^uSiek~)LvKW%!9x<|TE$BW$$`(w-(gh8KT z_cJ`o@F%(kMkCG&K94f|iIJ|}?neNjC9FHmbNY<#&-O^GdsM^U&ikIycjS~l#vWmP zB_!2RGsq~qq*!6&_L@Pa#sb^w$v?|9WB2<<{=fBm3H7aVjQ_j){RkX~HS&L_#~+dA zjwoG=DAF{RpXSp#h+jLO$QO{S6@QinTgy^`H68VQdOiPsO2z)EGfvlu`kHaDg$SMI z(v|=mM1&Nro*p204j5N_u7-#yNHjUY#%xpgmkJqk#y~QemZceW5lF92CKHY}e+9P5&+A$Hc5jG{ukQFu4CrKgm|q~^A&mZr@br7~#>>#SoUO>)^i z0w*jPp(FxXY`JuHpPG|wofXU^)&vj>QzZbw;gV!Sl>sERIC4}mrCkPW>CM;SQ39MT zxngwK-fNXRdSmU$)SOIXem0Ruqgi+nj+&7OafU;u4G%5sIqe{erq!KJ z7jv1p$y9r+@@8&EZia!-D~FQ@F?{e~I0_h3cSDM^&x{>BsO9$G87~=Mh6|q~=&P#N z4MIYDlY_X0!o&9VpQa&%()PpY#jzV6Qu1L-44)`_WXjgQQ4)kcX6&yVKRh-HvzPBr zCYl3@&P1{m9Y_A!YX?SAxWwjVvva^;h;-zhs~j}al^+}Xm+o1x3ztuk;Zs;2JT7a_ zx^*r4=ACYMgQ51;MzLs`R2Iww&xtpQu{n-kaHFFIET$n^E*OlLl5P3@jsv14)mnRF z65^&L5I4#^q<*lLh;WW8JUqsv&^x97pL&n)&p5_-VL}{RysipLFj<5(Hr9GPKiair zV)LGf?YnloGQo%GTuX4h)#0(ewgmxGgv=k;ZPAs-s+IeyyNnAa#N&dCMYx(UwQJo` z&yOdz?AmNnG%CjbwO>Bm76EGR4bd+g}&+nG)(-Yb&OdC z{m)_|-fsh!`Ljged{$Vv+@Qn}p`rx#=4yFua`nr51x_8Sp|!+|4wOy@4|>komDg($Q7%`% zd|-UMHZv%D5_91fh%1#iMTs8B2zEH=lK?(88XY|nt_Xespa-OL>%hIW=rcaQ^(R~X zzVE&4Z#X=*;mPwKI(OH(hu3d=;tA{V$Bn^#`}_d_Dsuku@$K8UZrys-&*Vc_RW_Uu zSjmqnf11-Jr}Ce!Wi2U^H$}baE841cUjey65lp+|)Xlk3`rHe(5UTocwzmiOjgnLV z2Q3L2r5k~du)m<*VCMWr1T#^K^HL-SB$9=60&m#UG=1Fn^!fCDQwsl@Ztm%l)@!P< zuZ{Z5qsU}7Dn(Vn$)l32(-3DhKMbSr8j8b1XL1BOPYjqF^o(&V?$6$vY&6icOqk1D5ykWk` zsZ@g?hc`y>R!6K<>nJX=VKB7IWfKS0hTxabteP2izGuF;DPVq>3S079dUkK#z4`aDBy-$o3d?$e(X7Xm9ZJV=;wy~mWb}{pAXI*RgC1>Y&<8^(d1NJ>o6GJc#$h`e zlb~WlnIB1D&Csp|-AV%1EPkFo9M0$rx$uUuWILEzp+JN_P`O_bAr;Vms8}3Vz$vm8 zeM?e1sqp04=VJRzwPRF0j>g*xwbz0|+f~T?ai=pFC0ngKUvzn*CXSmvFdEY)^8}`gb$O| z5{)*RJ!TK@&+8u^#tDe5OLhBOBYMB!mHQW;J}xxM<65oKPZ)=%lhLkRqcl5i+-<^{ z(6!<~?02mR;XK?Ny?V8%2c5<^rcZQ9J#spHSyqw$-0Lf?5>*rK$M%6rb+pPpaFsZ4 zP9FFje00Uzbs?Kv_cI5@KjRxA9GOb{K^cX#}343YHG_`@aWj#y`TY;D$ zqTDt%7Xm@g!(KMzjU|N0Z3F(uY(&RshMTPOEWX&?(q=fvZ|Ljiofk=maJLRiuGPr9 zBN?%+ZQI5i5XwZj7ktdfxn&uzAW@NJNP9$g=s}~M+p7a*(1-O_Xb^*H3dzwoq)jb` zl}jdj8$h;7=5omd5n}NZO)H(#9|=KSv?IY(mAA3R;(lbLeD!|S{LMU z3tC&=(bG9-S#j^CP2RX=4R+qVoZ}umn*%@YwW86vZL^l=^Ml#!U_QTmR@>ZY)DoyI zxJHK~X53{wRA=+D{d0t?=%@kks<2F%V~9!>k3lJl?mJ#KUpDV5m!B9NEeo96&R!F* zJo$NlU%1z7lHEqL>=`YWkCw|leP*BenEc!P7p&uvsE;u(tn&s)ZRux<*DPCS6tfX4#jji!^fOjdV0u;SPS)1^Tl z*eaz|Ld!{Y?5?e1N^}egwM|Q21F|+bii)iiD*{bIp#f)>2o?A5-%IMN@$mwq4g-s% z%TY8(nV!b?!V&BpAOCvu4m^l`FfcW%Op=HgV^j0|Z_Y25zgfPi>w)eEjpa3iRqafb z8%OVNe#i3W2ZoD>i-);i#`1}(4rI2%zb6@^w}tXsEkj)hb&7~X{m7JmDhodYKvN(-pu zztN{|z7RANrIea@R11=*`e!@NMDmB?<+6BHoRwZaqsotJ@J7_9SFCnhClqps8Vgzc{+%agJG+9>;E)f;~jj=am45Zj|izk zbAEb?)yyA~ReKu@RsG1YMXYKCc`5pkDN~+y0npQ*#=W)ivU#&h1UZ{8W=KX7{JXI5 zf}{-<7#f&oj|;8GT4W2x^}}vbbkp;LWD8*s_9zBlERk|0HVB9=^mCq5MrgNa6z1t| z-7Ijg?E_1kY@ECS+Cw}){@{ujmAHclh*r9J3T~N25SKLr`}SGK_=g~JTp(@2;CWog zw_s8+UX>Xht9VmP;WAbH zCNUE5Ny*I;6d59@8k;_DtoTI)l*2)zdQAIk6CfAB<|;hA(%C$#6m61EmmPs{Se(v% z&LC9Nn+j>;vf+v(y?%pSx581+2>FA|#JPwHPUqrIQ6=#hc#Ozs;zJ!Ep2G@p>-45 zbQ#Wls`uBFaJUnegtC>YL()D+{kq6m_1aItg}l@2tots$w2$ z_tx`1^ut@v{m^+@2b?e-VxDXU(`AWRzh+fMZ@br}>fSL*A^M4?;mo2{m4a5@4C)S0 zqTd;-;@9*-gj{Zw&Y`26&E;iadU}k|{E^DjFcz`kK>V7HkYET>XHAbn8oVGlfB9qA zCwh^b8HFlii=_|-&2$jA$vHdA3xc;R!9P5BeWELpkCB9_uG;woZ+aSyW zj+?LuJpZbB@EK&YJ@HFyq{q=aokPs&IJ&26uruD~c+Bxd`V8boa~)O169H9B*Yd3@ zp2W{t(W6Pl6O*w$M^_b3B?t!Ih-AM^BY0HLSOjMl;#Mg6s>&gFHi#AEE7g&7preCWCaMrKY81~%G)ah)-`)O+HlaU!-M1$@JQ9iI zYFbcN#pj--sz}I_*J_!cN@bx60@NRgeV;i{GzSLE;($4z zbn{wYA@pJclma>Olyu^h@dl-KrM*(TsvZpVe%<5sL@)k+r{p>{uClErs1r?7$7^}3 z1PiCdCaAe=-p)@2Y0c-d<&H}QP$P-v3n*0+7-fSFiL926M1cipjYiT$6T1Ieu`VZ3 zo&8F>s7rk!(uK;&v!1o}sW=!Mitfw?$ zFBWq+nOdt+Iy`qW;>!D*<_##F*{ch)PTxW^QYb{tA=EK)7fivnaa*3MM4$UyBjVj7 zzV5c-M%7sva>d9BE_QKW@CH@6M()+i=*eV^YZi84by)C=WMIL9K(g}85RyQr%9#O} z3l~$T5{cOB?35rNziXsdlmQW6ZDxUaLM?Fh%23?jwQ#$>AgLjKd(sWR? z_<4${4)dtI2Jyf=C)OQX4+ABPynG;hYM0Zs4B^bxkcf77cSjNcy+otF9zQ@!*a$_B zp9@8My1HJC^Ep#sLr7MLU?n~)9?z?Sbq0UN2;&bx7>{Q++S<4glIq6tD9~VDc3?nV zM#U;pJH|qtr|;}&cXYj^QIX~-@zLI~EIZVQn@@~3MH>bhbAxGbm%!XeXT#7K?ds~O zyri!2Q4u{nVdgC6ortIMx->?&Q%tw`yzG;D(ki^{M8Efz@ip`WIedjgPowacpA>5UPQORjVQ#v?`uJq)YZXyPmE5P%N$jr4sPW9Euer zXq*G+c=Soi;w$fa@S^DOe>g%C{Oxc&_mQpdt^J>P1p)3A*8R$!EIT;Hcm>L#Hk_z9 zB}RJc=h^yI*~yuUlpedtx@B)0<6nww+eB%mNWC0Ij*;zt$}mN?$-4Y^Q)Is^%f1q2 zB}L95$5)S)>h<@(igUcqwpd~y%f zy7FJ9NL?wiZ$G8FzgkzWQQcO(pX$1tH&wS^+AHUh?NVf2?&~spUAD>js`oF~kb9Fl z)njDcq{ua7dAYq@-7m*iuTgDBLtP!YX7yM(MwYAf<-dB2oV$f0|FTW$-f1u2#lPI^ zx9tBf+5gq;2J43LZGL273*}MD=PA1>$0%Q>+)lZN@>|M3Ib3R4);~j$x}WD9Qb)?o zl(`f+4|UKFIMn&2zLZbc|Bvv0oN^yUpvV6iBm`Oi0tMZ@aTlea?$=>FZ*O~pf7GA` zLtpJb#Q%PZ98WtPvR{t<2}RB&?b|?k$>EgT=LYrBSU8LqC|_e)K9XlU?|6v#m7h7^ z>wMmAy8GRid)9c4dVlBJ<2&YmEU+|iY2c^Cu6{7ICUjlsnE814n(*_n-Lb!mJ!J*0 zmlDq<=O)ie-jn=(YAAI^>WitLHY{!UMLLqcJLAZ#$xLK^klm2|_uRW0S2RA>`0b{R zO}8~Y*L-R7z0JSPU!DK{j9XeZw|u+-yWHIa z-4D;cZuX%$XUuiZ-8A>rdCqw==Up)GgS~rtpYO}`E$+Lm-|Sz}|7>w>@wVcV0}BTB z3_dWlX6RU{sr2{r&H2~NzxTBAg5HJkh4(J}{;)YbG5pG+V~g7se{{*FC3h@2wsh^% ztC!7OwszV0vSZ6$Tt2XT)$+TRKQa;-X&bq&JhS}l=*H0-MxR{q{goH2im!TL%{}jU zV6AuUt*3wZjQAN7XS&b4^{lhbdgg5B*~90!&-vZD4eOp9%a83j_q_A2Iq&)N|83&~ z@9cl)tru*#aNmWW-gMTcpIx-|qI)m;!RA}GJbUrb#dlo%;w8hEJhC;i_1SGr+iu&w zamPbDb3329^hcNVU-s6-!@KU;^%n0&h}pBoQPE$o#eq-MnN zm-e!Y?L+pmo8^z%%O1Q%TI^*ny7Ue9a*%oC5oQ+Rjo8w{+4QnLr(V|Q)XVyudRd=S zFMBz5+&)&H^DMH_&cRdU5_s{;St?PkM1J4R`ep3fK-tZfooaszT>D)7Y5vGjXKkCa z^O7qrpHrH1<(}PFT(<3x)kn_VhE3@z#{~L=-G8+93e}c9+{<>3yIi$!3vJ$p&r6Hr XVssBJ#01M7olcSaV(fF*fAI6)u)>;0 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/fonts/Pe-icon-7-stroke.woff new file mode 100644 index 0000000000000000000000000000000000000000..c205e6fd3cae5dbfd991d499c7495c9228a804c3 GIT binary patch literal 58556 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-icon-black-1.png b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-icon-black-1.png new file mode 100644 index 0000000000000000000000000000000000000000..cd702885b45d555982a9207ad95cb571016e437b GIT binary patch literal 15510 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-white-32.png b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/codemr-white-32.png new file mode 100644 index 0000000000000000000000000000000000000000..0201baefade8077c9e1e2a1fb4871d9e93bb471e GIT binary patch literal 1254 zcmV+_)5rR-bL6Hgy3Xl>B@e)fxkyMCRhmee-h*%*nHeeaY z9`DZX>^$zBd++yA#72p|JG&c&BTX@*Gv}OdzN_!v5f}oEMq}%!l>3G6&%pC`JLk3$ zkqkVq?U)yhF;}g%^{J_;WKd1fkHE~b*=!!%vSrJ0Ddlrg%2^@AB!H2%_XPj~P!Lg* zh%P(lzRR-gT(w%gB7~q}io6R^6iq9o-nZ5+Ff;LhAR@BXE-0l=udJ-h3~kKJUZ>M} z*%)(i7~?KM*cfvu>vUdWW^YjQkt9h@I_IK$HQos4T$Jbe8_ZlOHJ_WC3-UaFi-@xO zWxfs~%F;AFH8(dG^bC-u>1)op&iyuDhjXqI$MNf3&7&wfY^}ZVf0?ht7*lVxT94gj ze(l<|idO3LVT6dNaMni7+7=P%VcykBeNnI1M*+YGfT^jeV}204ILIP(*50(veOna8 z&!qJt0E|>Bd!+9_H>ecV|o^=Yfsn(S9yy(0%u99=km2o5xNFqx6XjK7h9X7zW z>FEc2-``foA?8#v^I{*ZNztcG-7q#bwqHuQvy8*QqGaYvWvdl{u-3|90|Y@ZE`;dW zUS?+J+`KG`;#X$w^mGRh3~+SY2+u1&e=u{*%)j_qmR%ShAHNLX$*x3TAprhi=D-+p zFbIN?5?uix1#l%vlAB{=W6PfB?d?W%&ixU`@dW@tp6BlnZ9aJs5vOVTHUOk)`n+>) ziJ4o>9QC+b&bb@ycKgVh?uR|5Am@30>c2E$7|t4FHth$-n5!!*D>L)+^CLx3d{Z`B z??j&G9|1tC)q31oyWB&iu3=881r|d(KuAA)jX}#XM>urLn(C{0OB}4>YQ6$e_j;D zxt_afv)O#a81p;d?$HMT5I37gopX(016XVSjN|xVtyc4tQeQIP-c^$%dAMW|17R2* z(^~(yzL2!mpA2ixyw*ac-UWax%U&&tVlIlJr%TO&+b5eij<++jOw;tRv-Z}#1X!#1 zO0={z&CFwIn(pK-Cn3|GOa^q zj@NE^$O{ZKecx}Cd6bS=W*${a9hXw>lTr@#mus!{l~R`{CMM1cA#5++zonN?TEWqf Q1^@s607*qoM6N<$f?TRlegFUf literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/default-avatar.png b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/default-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..ca9fa88471a83781acf0c00784d5b4bad2ca487b GIT binary patch literal 2864 zcmW-j2UL^E7RNsVNa(R3EDs{E;vy)kf(p{hO4(f=^5CI7P!!!&Tv3qfDgp^z2@rZq zA=E&qp(H_qpaDce&U0gv&KxlE3GC={^K0?*Bfdpn@U|u&5K@?D0DU-N}QX`)LrgH2^{A zEeMK=g`i!q@x&bn+ILhLdBhEZq#^g;Jb(H0X|bpnmtRm+SX44SJ(HJTI5sxEwzl@_ z)xh)T-5Hr#TU%Qdl~r8sI}T@Pcng&CS%> zT1rbxYfUYsth}<8Qb(z)r+`u4(A3miS65$G-_Y3D)X>maN-8fUm6hNKRaNBb>YCyb zd__f7O-(Jaw5*`8xUH?7SV|(5RpjOsRDzR{Yw!djgTWvWOUuhE@r2Tb#wJh+)M{*M z!r_THJfWFNrP1iEt!?$7dQ)>-TU&NcUQTX)3s`Dz@95~r&dtxt$)nL|*zDY_?A-Qt zS_uwMqk~`+6cuB$z}~`~yn@WE90sE!6PuHP%}&qAO3%R7)YiQl8JV1%tgCD2c-F~e zc76Exv8jnVH#axGupkzTOG@zHzI}^{iHVJkjf;yzp-^ZvIzB!=At50#F)=AADLFYg zB_$;_HTB7pCr_U~O-oC|U@+zyKlx9zfymR|iM|nSX=^_hNQ+bv*}O>F)07>3Q)2DEyMeV)gd+ z_VxAk_xHa7P8t|^{rWZV1Dnkr0-gX)8V2IOc?)a-jP(w18W{yHdH?{B%5D4by0mTKOQ1}TrcyUoA5-lw)0jkT(%PT7@ zpFe+IU0nq>USD6ANF*B@8(+SB+1%U&X5QZ3-r3pN-QE5A^()|imifzG2$HLIakTS{ zZ>g;1cShYneyY;rmD| zR)yt|qtlYfbpLSAY+%t=sK3{-q&v8`Nvgr>kx$6!$Qyph@r^1)f?Kxp$QhL9P zR`8nA{$Zju#&>M5lAirvSyu!je%i7qJ9W(-1umC!;e>`#0!Js^PZo96G)cCR>~E$O zu4m^@S4ecw)pAyBA>V^5!p6M}dJ=s!5X%(%JyWb0GXh;3VW|uA{f2jTZtB%6^tx-}ODGdcb-AGb1hdzaQC%zwUgQWyTV-#oUlvO%Iq#<#)s4Igu!V<$T+

    *?EPk9lm`;XXd9~ zaIAjOWXqT++!j8H)Gtn)2#Tmw>rePaU4GqV$7JjK`E?Ya zQ26lEa&lcFg?({6H658CjBrHlgiN#1ie)ASuk*)SN@gF`AZ^e-);fbUQdp|6!vZ#$|3s%P@?xZ1_K-N1x3~BnKgytM!yw zTKBfey^nHJzQmo_pg`nL_MJv)H>Gr&>8>Gfc($h2;$f6&)sn!)%>+)MJKd5e?3nl7 zmJRk8XM3qQ&aP4`!^`y1!cD_KuF5c}1$SRdU7u%{gyA8}h6!6$Fo7ZH7f``n||U8_XLb`PWqSwpRo6k(j#;av4MfL8S7@ZREes6uMQsd3@<~VjixS$JSr%Eq}AH270sI zV7Yb=@j6EHgPEDxML)0Lit{IDnue`hd0wmr8f|OgKLg3|C`zbJXD~AE$AhUakp8w= z-zEivX%`1>nx2!=eLd3u%qExP#ky*$`P5Q_P zT@LRHS5)q;6pGnu;oM-*tk8Wkp0ZJHvwypVts=CJVEarEyt5d!;Iq4kzWM>IWR@_it}|tE->hi{|d`Xr8)>q+W*8w>O{qaRaF|_;X3L zbsO2IR`Tar^!o0@Wy`?a4usX>g-3J2QBg+|<^wQ7fyREjQ9gS+f~&~6>m3kah3E*^ zkFW2u-El8ot^|Dp?H=bOO`McjdS6dtzj7qfE~ ZLgvRUj{Gpa175q3%P($@6np=;{{!!q3-15` literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/favicon.ico b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7482a653daf1130d6dea4ba9a92259a8cf15c87a GIT binary patch literal 1150 zcmeH_F-`(e6h+^6Y={&PBZU=}F`+kc5tPKZ13H6^p@Xmhw<9GbE<<}0s3=f47yeED zB<=v-${Wq#=&@RX63=ee@lalIfsEBhb5 zC_QWKxW)+k?i;+XjI@1s?YN#1<@0}YeuZvETAp{6)sE{9@dLMR-X2&UQwsn9 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/loading-bubbles.svg b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/loading-bubbles.svg new file mode 100644 index 0000000..4020b4d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/loading-bubbles.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/mask.png b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/mask.png new file mode 100644 index 0000000000000000000000000000000000000000..429360d5ce730f002b7413fdb94bcd261339b5ce GIT binary patch literal 756 zcmeAS@N?(olHy`uVBq!ia0vp^0YEIv!NkD8cyyD`Js^j(z$3Dlfq`2Xgc%uT&5-~K zDkOUZ`7$u%&R}3D?qgv1b%ueV3kcwML zKmLP({*A-*E2LeiU=QJ1RAk@^Je8B|IkoT7jCe!ITtr_Iw7T7H-mN|a>_~Iq6)cxmOxaCz}U%#Ui=s2K3N3I^^Y%vgEy)dEq$tzzSg&VCE z-hNH8D(cxBVu|TZ(-bt7gnr7EDXw`FXuQACea6q3EX)??i)Ss{wNCy>i$Lu4wXeJG zt5is|ZI6GmcmLtk$Y+utw&ikeyY?(*od6RG}N|3)b--Fx0`gf zzb;_}x%SBnuxnk_#RT?9>t``*iRooAcc!mZnAfW+aiSt1qKtFX^3=I|_~e*B|L0l2 zpZ(T=$M^C9X3f)^UR!0a4SyS4G4HvFZzGFS$8JvPnb8pYyQ0%A4xY&>OYj9^0NMc%^60)#}<5!Gm85<1XFVdQ&MBb@031k3nE(I) literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/new_logo.png b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/new_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..8e2192bdde5cb354dd4db5f1b7d55de774c3a062 GIT binary patch literal 3557 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 literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/sidebar-5.jpg b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/img/sidebar-5.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7471ab8e2fef9a071b93321963660f9fa6960714 GIT binary patch literal 280836 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%0A~`8*jGY*w~u8LamVc4oyy^`HHqR$qaN_oy<_ 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%0DuDx*(!!P26!%nXS^Y2jA>(y?t(=xAKbRL~;;| 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
    (rZcrY@enMMxTMbaQQR$2$pm%`uegL-%Gj)9hoS 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

    o^1?)&%uv7A^X2@f|Q0QPLF^^? zph1O{l3~P<_sUVX-(d17;jS+f{@TU4t90ukO_Hcttk97W&Hj+{cy+P`@Lk{}=uS7n zHil+6=&4C`(O%}gi5lefgMo&dF$6GWsC4rexlRPS08Lj_1BFH9-!@WE3h*7%vs{@z~qi>LIe9e{snTF;*8r1`MO;mf1$s z4BGf@Z5j1Uu8k~dAaGSR+aWNR`QCMRsU7P2!be{GfbUTEUWP5MYdX)r#)ErptH)UGJJYV?)YKSJ>_8Xh=D{sFT= z-Oj3<6ZP&A=&h(`p2wHS(6XA?Tr$Pg;yW8imoc{ftALY*Pr+JKCK~O<5Zufi%S(rO zs%E^mu#-)6du_2Z{pj?(KMvfJ36sw#xjvsYCWK~FiAK%7=ASblmK6F8iZ?slty~`G zzuOc+$_+-mKDeO35d9Hpo2Kj77oBlv*zePra;^O}_ATt?tGb^e%YlSty69-CZ@0-} zP35p_$Wj;;?Y#yW%(rF^eXo#i@>$Jd1*PUR*1R>RYUo)uw8RZ@FMWC79ouJMZ?khK znxYa5>;T-bUTcKe&OEQ2`lI^F9QA9l8HSs?x!de!|7N_*W841g1GjfR3QHsl2nZpp zO|UiS4(|()TU|D!+dfh@Q~3f=6ztx#JTFmg5&hd{-w?X)b;LF9Rw}4SXm9-Zcboiq z^*EXds?6yq;u_Z$n#8O%GrtB|w~0M?o5wAXwx(*~7ν5qic=WYF=sJwGlHV7A>F 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�+%{J4bcp~7@ubq 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 ZS2=0^r}3h@>1P;)1e0HJl(6x+|Jk!)inss( literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js new file mode 100644 index 0000000..cf05f1b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-checkbox-radio-switch.js @@ -0,0 +1,502 @@ +!function ($) { + + /* CHECKBOX PUBLIC CLASS DEFINITION + * ============================== */ + + var Checkbox = function (element, options) { + this.init(element, options); + } + + Checkbox.prototype = { + + constructor: Checkbox + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.checkbox.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.checkbox'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checked = $el.prop(ch) + , e = $.Event('toggle') + + if ($el.prop('disabled') == false) { + $parent.toggleClass(ch) && checked ? $el.removeAttr(ch) : $el.prop(ch, ch); + $el.trigger(e).trigger('change'); + } + } + + , setCheck: function (option) { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.checkbox') + , checkAction = option == 'check' ? true : false + , e = $.Event(option) + + $parent[checkAction ? 'addClass' : 'removeClass' ](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e).trigger('change'); + } + + } + + + /* CHECKBOX PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.checkbox + + $.fn.checkbox = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('checkbox') + , options = $.extend({}, $.fn.checkbox.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('checkbox', (data = new Checkbox(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.checkbox.defaults = { + template: '' + } + + + /* CHECKBOX NO CONFLICT + * ================== */ + + $.fn.checkbox.noConflict = function () { + $.fn.checkbox = old; + return this; + } + + + /* CHECKBOX DATA-API + * =============== */ + + $(document).on('click.checkbox.data-api', '[data-toggle^=checkbox], .checkbox', function (e) { + var $checkbox = $(e.target); + if (e.target.tagName != "A") { + e && e.preventDefault() && e.stopPropagation(); + if (!$checkbox.hasClass('checkbox')) $checkbox = $checkbox.closest('.checkbox'); + $checkbox.find(':checkbox').checkbox('toggle'); + } + }); + + $(function () { + $('[data-toggle="checkbox"]').each(function () { + var $checkbox = $(this); + $checkbox.checkbox(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================= + * flatui-radio v0.0.3 + * ============================================================ */ + +!function ($) { + + /* RADIO PUBLIC CLASS DEFINITION + * ============================== */ + + var Radio = function (element, options) { + this.init(element, options); + } + + Radio.prototype = { + + constructor: Radio + + , init: function (element, options) { + var $el = this.$element = $(element) + + this.options = $.extend({}, $.fn.radio.defaults, options); + $el.before(this.options.template); + this.setState(); + } + + , setState: function () { + var $el = this.$element + , $parent = $el.closest('.radio'); + + $el.prop('disabled') && $parent.addClass('disabled'); + $el.prop('checked') && $parent.addClass('checked'); + } + + , toggle: function () { + var d = 'disabled' + , ch = 'checked' + , $el = this.$element + , checked = $el.prop(ch) + , $parent = $el.closest('.radio') + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el.attr('name') + '"]') + , e = $.Event('toggle') + + if ($el.prop(d) == false) { + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + if ($el.prop(d) == false) { + $parent.removeClass(ch) && $el.removeAttr(ch).trigger('change'); + } + }); + + if (checked == false) $parent.addClass(ch) && $el.prop(ch, true); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + } + + , setCheck: function (option) { + var ch = 'checked' + , $el = this.$element + , $parent = $el.closest('.radio') + , checkAction = option == 'check' ? true : false + , checked = $el.prop(ch) + , $parentWrap = $el.closest('form').length ? $el.closest('form') : $el.closest('body') + , $elemGroup = $parentWrap.find(':radio[name="' + $el['attr']('name') + '"]') + , e = $.Event(option) + + $elemGroup.not($el).each(function () { + var $el = $(this) + , $parent = $(this).closest('.radio'); + + $parent.removeClass(ch) && $el.removeAttr(ch); + }); + + $parent[checkAction ? 'addClass' : 'removeClass'](ch) && checkAction ? $el.prop(ch, ch) : $el.removeAttr(ch); + $el.trigger(e); + + if (checked !== $el.prop(ch)) { + $el.trigger('change'); + } + } + + } + + + /* RADIO PLUGIN DEFINITION + * ======================== */ + + var old = $.fn.radio + + $.fn.radio = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('radio') + , options = $.extend({}, $.fn.radio.defaults, $this.data(), typeof option == 'object' && option); + if (!data) $this.data('radio', (data = new Radio(this, options))); + if (option == 'toggle') data.toggle() + if (option == 'check' || option == 'uncheck') data.setCheck(option) + else if (option) data.setState(); + }); + } + + $.fn.radio.defaults = { + template: '' + } + + + /* RADIO NO CONFLICT + * ================== */ + + $.fn.radio.noConflict = function () { + $.fn.radio = old; + return this; + } + + + /* RADIO DATA-API + * =============== */ + + $(document).on('click.radio.data-api', '[data-toggle^=radio], .radio', function (e) { + var $radio = $(e.target); + e && e.preventDefault() && e.stopPropagation(); + if (!$radio.hasClass('radio')) $radio = $radio.closest('.radio'); + $radio.find(':radio').radio('toggle'); + }); + + $(function () { + $('[data-toggle="radio"]').each(function () { + var $radio = $(this); + $radio.radio(); + }); + }); + +}(window.jQuery); + + + +/* ============================================================ + * bootstrapSwitch v1.3 by Larentis Mattia @spiritualGuru + * http://www.larentis.eu/switch/ + * ============================================================ + * Licensed under the Apache License, Version 2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * ============================================================ */ + +!function ($) { + "use strict"; + + $.fn['bootstrapSwitch'] = function (method) { + var methods = { + init: function () { + return this.each(function () { + var $element = $(this) + , $div + , $switchLeft + , $switchRight + , $label + , myClasses = "" + , classes = $element.attr('class') + , color + , moving + , onLabel = "ON" + , offLabel = "OFF" + , icon = false; + + $.each(['switch-mini', 'switch-small', 'switch-large'], function (i, el) { + if (classes.indexOf(el) >= 0) + myClasses = el; + }); + + $element.addClass('has-switch'); + + if ($element.data('on') !== undefined) + color = "switch-" + $element.data('on'); + + if ($element.data('on-label') !== undefined) + onLabel = $element.data('on-label'); + + if ($element.data('off-label') !== undefined) + offLabel = $element.data('off-label'); + + if ($element.data('icon') !== undefined) + icon = $element.data('icon'); + + $switchLeft = $('') + .addClass("switch-left") + .addClass(myClasses) + .addClass(color) + .html(onLabel); + + color = ''; + if ($element.data('off') !== undefined) + color = "switch-" + $element.data('off'); + + $switchRight = $('') + .addClass("switch-right") + .addClass(myClasses) + .addClass(color) + .html(offLabel); + + $label = $('

    ')).parent().data('animated', false); + + if ($element.data('animated') !== false) + $div.addClass('switch-animate').data('animated', true); + + $div + .append($switchLeft) + .append($label) + .append($switchRight); + + $element.find('>div').addClass( + $element.find('input').is(':checked') ? 'switch-on' : 'switch-off' + ); + + if ($element.find('input').is(':disabled')) + $(this).addClass('deactivate'); + + var changeStatus = function ($this) { + $this.siblings('label').trigger('mousedown').trigger('mouseup').trigger('click'); + }; + + $element.on('keydown', function (e) { + if (e.keyCode === 32) { + e.stopImmediatePropagation(); + e.preventDefault(); + changeStatus($(e.target).find('span:first')); + } + }); + + $switchLeft.on('click', function (e) { + changeStatus($(this)); + }); + + $switchRight.on('click', function (e) { + changeStatus($(this)); + }); + + $element.find('input').on('change', function (e) { + var $this = $(this) + , $element = $this.parent() + , thisState = $this.is(':checked') + , state = $element.is('.switch-off'); + + e.preventDefault(); + + $element.css('left', ''); + + if (state === thisState) { + + if (thisState) + $element.removeClass('switch-off').addClass('switch-on'); + else $element.removeClass('switch-on').addClass('switch-off'); + + if ($element.data('animated') !== false) + $element.addClass("switch-animate"); + + $element.parent().trigger('switch-change', {'el': $this, 'value': thisState}) + } + }); + + $element.find('label').on('mousedown touchstart', function (e) { + var $this = $(this); + moving = false; + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.closest('div').removeClass('switch-animate'); + + if ($this.closest('.has-switch').is('.deactivate')) + $this.unbind('click'); + else { + $this.on('mousemove touchmove', function (e) { + var $element = $(this).closest('.switch') + , relativeX = (e.pageX || e.originalEvent.targetTouches[0].pageX) - $element.offset().left + , percent = (relativeX / $element.width()) * 100 + , left = 25 + , right = 75; + + moving = true; + + if (percent < left) + percent = left; + else if (percent > right) + percent = right; + + $element.find('>div').css('left', (percent - right) + "%") + }); + + $this.on('click touchend', function (e) { + var $this = $(this) + , $target = $(e.target) + , $myCheckBox = $target.siblings('input'); + + e.stopImmediatePropagation(); + e.preventDefault(); + + $this.unbind('mouseleave'); + + if (moving) + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)); + else $myCheckBox.prop("checked", !$myCheckBox.is(":checked")); + + moving = false; + $myCheckBox.trigger('change'); + }); + + $this.on('mouseleave', function (e) { + var $this = $(this) + , $myCheckBox = $this.siblings('input'); + + e.preventDefault(); + e.stopImmediatePropagation(); + + $this.unbind('mouseleave'); + $this.trigger('mouseup'); + + $myCheckBox.prop('checked', !(parseInt($this.parent().css('left')) < -25)).trigger('change'); + }); + + $this.on('mouseup', function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + + $(this).unbind('mousemove'); + }); + } + }); + } + ); + }, + toggleActivation: function () { + $(this).toggleClass('deactivate'); + }, + isActive: function () { + return !$(this).hasClass('deactivate'); + }, + setActive: function (active) { + if (active) + $(this).removeClass('deactivate'); + else $(this).addClass('deactivate'); + }, + toggleState: function (skipOnChange) { + var $input = $(this).find('input:checkbox'); + $input.prop('checked', !$input.is(':checked')).trigger('change', skipOnChange); + }, + setState: function (value, skipOnChange) { + $(this).find('input:checkbox').prop('checked', value).trigger('change', skipOnChange); + }, + status: function () { + return $(this).find('input:checkbox').is(':checked'); + }, + destroy: function () { + var $div = $(this).find('div') + , $checkbox; + + $div.find(':not(input:checkbox)').remove(); + + $checkbox = $div.children(); + $checkbox.unwrap().unwrap(); + + $checkbox.unbind('change'); + + return $checkbox; + } + }; + + if (methods[method]) + return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); + else if (typeof method === 'object' || !method) + return methods.init.apply(this, arguments); + else + $.error('Method ' + method + ' does not exist!'); + }; +}(jQuery); + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-notify.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-notify.js new file mode 100644 index 0000000..f2f0c74 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-notify.js @@ -0,0 +1,404 @@ +/* + + + + Creative Tim Modifications + + Lines: 239, 240 was changed from top: 5px to top: 50% and we added margin-top: -13px. In this way the close button will be aligned vertically + Line:242 - modified when the icon is set, we add the class "alert-with-icon", so there will be enough space for the icon. + + + + +*/ + + +/* +* Project: Bootstrap Notify = v3.1.5 +* Description: Turns standard Bootstrap alerts into "Growl-like" notifications. +* Author: Mouse0270 aka Robert McIntosh +* License: MIT License +* Website: https://github.com/mouse0270/bootstrap-growl +*/ + +/* global define:false, require: false, jQuery:false */ + +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof exports === 'object') { + // Node/CommonJS + factory(require('jquery')); + } else { + // Browser globals + factory(jQuery); + } +}(function ($) { + // Create the defaults once + var defaults = { + element: 'body', + position: null, + type: "info", + allow_dismiss: true, + allow_duplicates: true, + newest_on_top: false, + showProgressbar: false, + placement: { + from: "top", + align: "right" + }, + offset: 20, + spacing: 10, + z_index: 1031, + delay: 5000, + timer: 1000, + url_target: '_blank', + mouse_over: null, + animate: { + enter: 'animated fadeInDown', + exit: 'animated fadeOutUp' + }, + onShow: null, + onShown: null, + onClose: null, + onClosed: null, + icon_type: 'class', + template: '' + }; + + String.format = function () { + var str = arguments[0]; + for (var i = 1; i < arguments.length; i++) { + str = str.replace(RegExp("\\{" + (i - 1) + "\\}", "gm"), arguments[i]); + } + return str; + }; + + function isDuplicateNotification(notification) { + var isDupe = false; + + $('[data-notify="container"]').each(function (i, el) { + var $el = $(el); + var title = $el.find('[data-notify="title"]').text().trim(); + var message = $el.find('[data-notify="message"]').html().trim(); + + // The input string might be different than the actual parsed HTML string! + // (
    vs
    for example) + // So we have to force-parse this as HTML here! + var isSameTitle = title === $("
    " + notification.settings.content.title + "
    ").html().trim(); + var isSameMsg = message === $("
    " + notification.settings.content.message + "
    ").html().trim(); + var isSameType = $el.hasClass('alert-' + notification.settings.type); + + if (isSameTitle && isSameMsg && isSameType) { + //we found the dupe. Set the var and stop checking. + isDupe = true; + } + return !isDupe; + }); + + return isDupe; + } + + function Notify(element, content, options) { + // Setup Content of Notify + var contentObj = { + content: { + message: typeof content === 'object' ? content.message : content, + title: content.title ? content.title : '', + icon: content.icon ? content.icon : '', + url: content.url ? content.url : '#', + target: content.target ? content.target : '-' + } + }; + + options = $.extend(true, {}, contentObj, options); + this.settings = $.extend(true, {}, defaults, options); + this._defaults = defaults; + if (this.settings.content.target === "-") { + this.settings.content.target = this.settings.url_target; + } + this.animations = { + start: 'webkitAnimationStart oanimationstart MSAnimationStart animationstart', + end: 'webkitAnimationEnd oanimationend MSAnimationEnd animationend' + }; + + if (typeof this.settings.offset === 'number') { + this.settings.offset = { + x: this.settings.offset, + y: this.settings.offset + }; + } + + //if duplicate messages are not allowed, then only continue if this new message is not a duplicate of one that it already showing + if (this.settings.allow_duplicates || (!this.settings.allow_duplicates && !isDuplicateNotification(this))) { + this.init(); + } + } + + $.extend(Notify.prototype, { + init: function () { + var self = this; + + this.buildNotify(); + if (this.settings.content.icon) { + this.setIcon(); + } + if (this.settings.content.url != "#") { + this.styleURL(); + } + this.styleDismiss(); + this.placement(); + this.bind(); + + this.notify = { + $ele: this.$ele, + update: function (command, update) { + var commands = {}; + if (typeof command === "string") { + commands[command] = update; + } else { + commands = command; + } + for (var cmd in commands) { + switch (cmd) { + case "type": + this.$ele.removeClass('alert-' + self.settings.type); + this.$ele.find('[data-notify="progressbar"] > .progress-bar').removeClass('progress-bar-' + self.settings.type); + self.settings.type = commands[cmd]; + this.$ele.addClass('alert-' + commands[cmd]).find('[data-notify="progressbar"] > .progress-bar').addClass('progress-bar-' + commands[cmd]); + break; + case "icon": + var $icon = this.$ele.find('[data-notify="icon"]'); + if (self.settings.icon_type.toLowerCase() === 'class') { + $icon.removeClass(self.settings.content.icon).addClass(commands[cmd]); + } else { + if (!$icon.is('img')) { + $icon.find('img'); + } + $icon.attr('src', commands[cmd]); + } + break; + case "progress": + var newDelay = self.settings.delay - (self.settings.delay * (commands[cmd] / 100)); + this.$ele.data('notify-delay', newDelay); + this.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', commands[cmd]).css('width', commands[cmd] + '%'); + break; + case "url": + this.$ele.find('[data-notify="url"]').attr('href', commands[cmd]); + break; + case "target": + this.$ele.find('[data-notify="url"]').attr('target', commands[cmd]); + break; + default: + this.$ele.find('[data-notify="' + cmd + '"]').html(commands[cmd]); + } + } + var posX = this.$ele.outerHeight() + parseInt(self.settings.spacing) + parseInt(self.settings.offset.y); + self.reposition(posX); + }, + close: function () { + self.close(); + } + }; + + }, + buildNotify: function () { + var content = this.settings.content; + this.$ele = $(String.format(this.settings.template, this.settings.type, content.title, content.message, content.url, content.target)); + this.$ele.attr('data-notify-position', this.settings.placement.from + '-' + this.settings.placement.align); + if (!this.settings.allow_dismiss) { + this.$ele.find('[data-notify="dismiss"]').css('display', 'none'); + } + if ((this.settings.delay <= 0 && !this.settings.showProgressbar) || !this.settings.showProgressbar) { + this.$ele.find('[data-notify="progressbar"]').remove(); + } + }, + setIcon: function () { + + this.$ele.addClass('alert-with-icon'); + + if (this.settings.icon_type.toLowerCase() === 'class') { + this.$ele.find('[data-notify="icon"]').addClass(this.settings.content.icon); + } else { + if (this.$ele.find('[data-notify="icon"]').is('img')) { + this.$ele.find('[data-notify="icon"]').attr('src', this.settings.content.icon); + } else { + this.$ele.find('[data-notify="icon"]').append('Notify Icon'); + } + } + }, + styleDismiss: function () { + this.$ele.find('[data-notify="dismiss"]').css({ + position: 'absolute', + right: '10px', + top: '50%', + marginTop: '-13px', + zIndex: this.settings.z_index + 2 + }); + }, + styleURL: function () { + this.$ele.find('[data-notify="url"]').css({ + backgroundImage: 'url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)', + height: '100%', + left: 0, + position: 'absolute', + top: 0, + width: '100%', + zIndex: this.settings.z_index + 1 + }); + }, + placement: function () { + var self = this, + offsetAmt = this.settings.offset.y, + css = { + display: 'inline-block', + margin: '0px auto', + position: this.settings.position ? this.settings.position : (this.settings.element === 'body' ? 'fixed' : 'absolute'), + transition: 'all .5s ease-in-out', + zIndex: this.settings.z_index + }, + hasAnimation = false, + settings = this.settings; + + $('[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])').each(function () { + offsetAmt = Math.max(offsetAmt, parseInt($(this).css(settings.placement.from)) + parseInt($(this).outerHeight()) + parseInt(settings.spacing)); + }); + if (this.settings.newest_on_top === true) { + offsetAmt = this.settings.offset.y; + } + css[this.settings.placement.from] = offsetAmt + 'px'; + + switch (this.settings.placement.align) { + case "left": + case "right": + css[this.settings.placement.align] = this.settings.offset.x + 'px'; + break; + case "center": + css.left = 0; + css.right = 0; + break; + } + this.$ele.css(css).addClass(this.settings.animate.enter); + $.each(Array('webkit-', 'moz-', 'o-', 'ms-', ''), function (index, prefix) { + self.$ele[0].style[prefix + 'AnimationIterationCount'] = 1; + }); + + $(this.settings.element).append(this.$ele); + + if (this.settings.newest_on_top === true) { + offsetAmt = (parseInt(offsetAmt) + parseInt(this.settings.spacing)) + this.$ele.outerHeight(); + this.reposition(offsetAmt); + } + + if ($.isFunction(self.settings.onShow)) { + self.settings.onShow.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + if ($.isFunction(self.settings.onShown)) { + self.settings.onShown.call(this); + } + } + }, 600); + }, + bind: function () { + var self = this; + + this.$ele.find('[data-notify="dismiss"]').on('click', function () { + self.close(); + }); + + this.$ele.mouseover(function () { + $(this).data('data-hover', "true"); + }).mouseout(function () { + $(this).data('data-hover', "false"); + }); + this.$ele.data('data-hover', "false"); + + if (this.settings.delay > 0) { + self.$ele.data('notify-delay', self.settings.delay); + var timer = setInterval(function () { + var delay = parseInt(self.$ele.data('notify-delay')) - self.settings.timer; + if ((self.$ele.data('data-hover') === 'false' && self.settings.mouse_over === "pause") || self.settings.mouse_over != "pause") { + var percent = ((self.settings.delay - delay) / self.settings.delay) * 100; + self.$ele.data('notify-delay', delay); + self.$ele.find('[data-notify="progressbar"] > div').attr('aria-valuenow', percent).css('width', percent + '%'); + } + if (delay <= -(self.settings.timer)) { + clearInterval(timer); + self.close(); + } + }, self.settings.timer); + } + }, + close: function () { + var self = this, + posX = parseInt(this.$ele.css(this.settings.placement.from)), + hasAnimation = false; + + this.$ele.data('closing', 'true').addClass(this.settings.animate.exit); + self.reposition(posX); + + if ($.isFunction(self.settings.onClose)) { + self.settings.onClose.call(this.$ele); + } + + this.$ele.one(this.animations.start, function () { + hasAnimation = true; + }).one(this.animations.end, function () { + $(this).remove(); + if ($.isFunction(self.settings.onClosed)) { + self.settings.onClosed.call(this); + } + }); + + setTimeout(function () { + if (!hasAnimation) { + self.$ele.remove(); + if (self.settings.onClosed) { + self.settings.onClosed(self.$ele); + } + } + }, 600); + }, + reposition: function (posX) { + var self = this, + notifies = '[data-notify-position="' + this.settings.placement.from + '-' + this.settings.placement.align + '"]:not([data-closing="true"])', + $elements = this.$ele.nextAll(notifies); + if (this.settings.newest_on_top === true) { + $elements = this.$ele.prevAll(notifies); + } + $elements.each(function () { + $(this).css(self.settings.placement.from, posX); + posX = (parseInt(posX) + parseInt(self.settings.spacing)) + $(this).outerHeight(); + }); + } + }); + + $.notify = function (content, options) { + var plugin = new Notify(this, content, options); + return plugin.notify; + }; + $.notifyDefaults = function (options) { + defaults = $.extend(true, {}, defaults, options); + return defaults; + }; + $.notifyClose = function (command) { + if (typeof command === "undefined" || command === "all") { + $('[data-notify]').find('[data-notify="dismiss"]').trigger('click'); + } else { + $('[data-notify-position="' + command + '"]').find('[data-notify="dismiss"]').trigger('click'); + } + }; + +})); diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-select.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-select.js new file mode 100644 index 0000000..a9ee735 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap-select.js @@ -0,0 +1,438 @@ +!function($) { + var Selectpicker = function(element, options, e) { + if (e ) { + e.stopPropagation(); + e.preventDefault(); + } + this.$element = $(element); + this.$newElement = null; + this.button = null; + + //Merge defaults, options and data-attributes to make our options + this.options = $.extend({}, $.fn.selectpicker.defaults, this.$element.data(), typeof options == 'object' && options); + + //If we have no title yet, check the attribute 'title' (this is missed by jq as its not a data-attribute + if(this.options.title==null) + this.options.title = this.$element.attr('title'); + + //Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.init(); + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function (e) { + var _this = this; + this.$element.hide(); + this.multiple = this.$element.prop('multiple'); + + + var classList = this.$element.attr('class') !== undefined ? this.$element.attr('class').split(/\s+/) : ''; + var id = this.$element.attr('id'); + this.$element.after( this.createView() ); + this.$newElement = this.$element.next('.select'); + var select = this.$newElement; + var menu = this.$newElement.find('.dropdown-menu'); + var menuArrow = this.$newElement.find('.dropdown-arrow'); + var menuA = menu.find('li > a'); + var liHeight = select.addClass('open').find('.dropdown-menu li > a').outerHeight(); + select.removeClass('open'); + var divHeight = menu.find('li .divider').outerHeight(true); + var selectOffset_top = this.$newElement.offset().top; + var size = 0; + var menuHeight = 0; + var selectHeight = this.$newElement.outerHeight(); + this.button = this.$newElement.find('> button'); + if (id !== undefined) { + this.button.attr('id', id); + $('label[for="' + id + '"]').click(function(){ select.find('button#'+id).focus(); }) + } + for (var i = 0; i < classList.length; i++) { + if(classList[i] != 'selectpicker') { + this.$newElement.addClass(classList[i]); + } + } + //If we are multiple, then add the show-tick class by default + if(this.multiple) { + this.$newElement.addClass('select-multiple'); + } + this.button.addClass(this.options.style); + menu.addClass(this.options.menuStyle); + menuArrow.addClass(function() { + if (_this.options.menuStyle) { + return _this.options.menuStyle.replace('dropdown-', 'dropdown-arrow-'); + } + }); + this.checkDisabled(); + this.checkTabIndex(); + this.clickListener(); + var menuPadding = parseInt(menu.css('padding-top')) + parseInt(menu.css('padding-bottom')) + parseInt(menu.css('border-top-width')) + parseInt(menu.css('border-bottom-width')); + if (this.options.size == 'auto') { + + // Creative Tim Changes: We changed the regular function made in bootstrap-select with this function so the getSize() will not be triggered one million times per second while you scroll. + + var getSize = debounce(function() { + var selectOffset_top_scroll = selectOffset_top - $(window).scrollTop(); + var windowHeight = $(window).innerHeight(); + var menuExtras = menuPadding + parseInt(menu.css('margin-top')) + parseInt(menu.css('margin-bottom')) + 2; + var selectOffset_bot = windowHeight - selectOffset_top_scroll - selectHeight - menuExtras; + menuHeight = selectOffset_bot; + if (select.hasClass('dropup')) { + menuHeight = selectOffset_top_scroll - menuExtras; + } + //limit menuHeight to 300px to have a smooth transition with cubic bezier on dropdown + if(menuHeight >= 300){ + menuHeight = 300; + } + + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'auto', 'min-height' : liHeight * 3 + 'px'}); + + }, 50); + + getSize; + $(window).on('scroll', getSize); + $(window).on('resize', getSize); + + if (window.MutationObserver) { + new MutationObserver(getSize).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', getSize); + } + } else if (this.options.size && this.options.size != 'auto' && menu.find('li').length > this.options.size) { + var optIndex = menu.find("li > *").filter(':not(.divider)').slice(0,this.options.size).last().parent().index(); + var divLength = menu.find("li").slice(0,optIndex + 1).find('.divider').length; + menuHeight = liHeight*this.options.size + divLength*divHeight + menuPadding; + menu.css({'max-height' : menuHeight + 'px', 'overflow-y' : 'scroll'}); + //console.log('sunt in if'); + } + + // Listen for updates to the DOM and re render... (Use Mutation Observer when availiable) + if (window.MutationObserver) { + new MutationObserver($.proxy(this.reloadLi, this)).observe(this.$element.get(0), { + childList: true + }); + } else { + this.$element.bind('DOMNodeInserted', $.proxy(this.reloadLi, this)); + } + + this.render(); + }, + + createDropdown: function() { + var drop = + "
    " + + "" + + "" + + "" + + "
    "; + + return $(drop); + }, + + + createView: function() { + var $drop = this.createDropdown(); + var $li = this.createLi(); + $drop.find('ul').append($li); + return $drop; + }, + + reloadLi: function() { + //Remove all children. + this.destroyLi(); + //Re build + $li = this.createLi(); + this.$newElement.find('ul').append( $li ); + //render view + this.render(); + }, + + destroyLi:function() { + this.$newElement.find('li').remove(); + }, + + createLi: function() { + + var _this = this; + var _li = []; + var _liA = []; + var _liHtml = ''; + + this.$element.find('option').each(function(){ + _li.push($(this).text()); + }); + + this.$element.find('option').each(function(index) { + //Get the class and text for the option + var optionClass = $(this).attr("class") !== undefined ? $(this).attr("class") : ''; + var text = $(this).text(); + var subtext = $(this).data('subtext') !== undefined ? ''+$(this).data('subtext')+'' : ''; + + //Append any subtext to the main text. + text+=subtext; + + if ($(this).parent().is('optgroup') && $(this).data('divider') != true) { + if ($(this).index() == 0) { + //Get the opt group label + var label = $(this).parent().attr('label'); + var labelSubtext = $(this).parent().data('subtext') !== undefined ? ''+$(this).parent().data('subtext')+'' : ''; + label += labelSubtext; + + if ($(this)[0].index != 0) { + _liA.push( + '
    '+ + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass ) + ); + } else { + _liA.push( + '
    '+label+'
    '+ + _this.createA(text, "opt " + optionClass )); + } + } else { + _liA.push( _this.createA(text, "opt " + optionClass ) ); + } + } else if ($(this).data('divider') == true) { + _liA.push('
    '); + } else if ($(this).data('hidden') == true) { + _liA.push(''); + } else { + _liA.push( _this.createA(text, optionClass ) ); + } + }); + + if (_li.length > 0) { + for (var i = 0; i < _li.length; i++) { + var $option = this.$element.find('option').eq(i); + _liHtml += "
  • " + _liA[i] + "
  • "; + } + } + + //If we dont have a selected item, and we dont have a title, select the first element so something is set in the button + if(this.$element.find('option:selected').length==0 && !_this.options.title) { + this.$element.find('option').eq(0).prop('selected', true).attr('selected', 'selected'); + } + + return $(_liHtml); + }, + + createA:function(test, classes) { + return '' + + '' + test + '' + + ''; + + }, + + render:function() { + var _this = this; + + //Set width of select + if (this.options.width == 'auto') { + var ulWidth = this.$newElement.find('.dropdown-menu').css('width'); + this.$newElement.css('width',ulWidth); + } else if (this.options.width && this.options.width != 'auto') { + this.$newElement.css('width',this.options.width); + } + + //Update the LI to match the SELECT + this.$element.find('option').each(function(index) { + _this.setDisabled(index, $(this).is(':disabled') || $(this).parent().is(':disabled') ); + _this.setSelected(index, $(this).is(':selected') ); + }); + + + + var selectedItems = this.$element.find('option:selected').map(function(index,value) { + if($(this).attr('title')!=undefined) { + return $(this).attr('title'); + } else { + return $(this).text(); + } + }).toArray(); + + //Convert all the values into a comma delimited string + var title = selectedItems.join(", "); + + //If this is multi select, and the selectText type is count, the show 1 of 2 selected etc.. + if(_this.multiple && _this.options.selectedTextFormat.indexOf('count') > -1) { + var max = _this.options.selectedTextFormat.split(">"); + if( (max.length>1 && selectedItems.length > max[1]) || (max.length==1 && selectedItems.length>=2)) { + title = selectedItems.length +' of ' + this.$element.find('option').length + ' selected'; + } + } + + //If we dont have a title, then use the default, or if nothing is set at all, use the not selected text + if(!title) { + title = _this.options.title != undefined ? _this.options.title : _this.options.noneSelectedText; + } + + this.$element.next('.select').find('.filter-option').html( title ); + }, + + + + setSelected:function(index, selected) { + if(selected) { + this.$newElement.find('li').eq(index).addClass('selected'); + } else { + this.$newElement.find('li').eq(index).removeClass('selected'); + } + }, + + setDisabled:function(index, disabled) { + if(disabled) { + this.$newElement.find('li').eq(index).addClass('disabled'); + } else { + this.$newElement.find('li').eq(index).removeClass('disabled'); + } + }, + + checkDisabled: function() { + if (this.$element.is(':disabled')) { + this.button.addClass('disabled'); + this.button.click(function(e) { + e.preventDefault(); + }); + } + }, + + checkTabIndex: function() { + if (this.$element.is('[tabindex]')) { + var tabindex = this.$element.attr("tabindex"); + this.button.attr('tabindex', tabindex); + } + }, + + clickListener: function() { + var _this = this; + + $('body').on('touchstart.dropdown', '.dropdown-menu', function (e) { e.stopPropagation(); }); + + + + this.$newElement.on('click', 'li a', function(e){ + var clickedIndex = $(this).parent().index(), + $this = $(this).parent(), + $select = $this.parents('.select'); + + + //Dont close on multi choice menu + if(_this.multiple) { + e.stopPropagation(); + } + + e.preventDefault(); + + //Dont run if we have been disabled + if ($select.prev('select').not(':disabled') && !$(this).parent().hasClass('disabled')){ + //Deselect all others if not multi select box + if (!_this.multiple) { + $select.prev('select').find('option').removeAttr('selected'); + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + //Else toggle the one we have chosen if we are multi selet. + else { + var selected = $select.prev('select').find('option').eq(clickedIndex).prop('selected'); + + if(selected) { + $select.prev('select').find('option').eq(clickedIndex).removeAttr('selected'); + } else { + $select.prev('select').find('option').eq(clickedIndex).prop('selected', true).attr('selected', 'selected'); + } + } + + + $select.find('.filter-option').html($this.text()); + $select.find('button').focus(); + + // Trigger select 'change' + $select.prev('select').trigger('change'); + } + + }); + + this.$newElement.on('click', 'li.disabled a, li dt, li .divider', function(e) { + e.preventDefault(); + e.stopPropagation(); + $select = $(this).parent().parents('.select'); + $select.find('button').focus(); + }); + + this.$element.on('change', function(e) { + _this.render(); + }); + }, + + val:function(value) { + + if(value!=undefined) { + this.$element.val( value ); + + this.$element.trigger('change'); + return this.$element; + } else { + return this.$element.val(); + } + } + + }; + + $.fn.selectpicker = function(option, event) { + //get the args of the outer function.. + var args = arguments; + var value; + var chain = this.each(function () { + var $this = $(this), + data = $this.data('selectpicker'), + options = typeof option == 'object' && option; + + if (!data) { + $this.data('selectpicker', (data = new Selectpicker(this, options, event))); + } else { + for(var i in option) { + data[i]=option[i]; + } + } + + if (typeof option == 'string') { + //Copy the value of option, as once we shift the arguments + //it also shifts the value of option. + property = option; + if(data[property] instanceof Function) { + [].shift.apply(args); + value = data[property].apply(data, args); + } else { + value = data[property]; + } + } + }); + + if(value!=undefined) { + return value; + } else { + return chain; + } + }; + + $.fn.selectpicker.defaults = { + style: null, + size: 'auto', + title: null, + selectedTextFormat : 'values', + noneSelectedText : 'Nothing selected', + width: null, + menuStyle: null, + toggleSize: null + } + +}(window.jQuery); diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap.min.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap.min.js new file mode 100644 index 0000000..133aeec --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
    ',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/chartist.min.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/chartist.min.js new file mode 100644 index 0000000..b69e484 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/chartist.min.js @@ -0,0 +1,9 @@ +/* Chartist.js 0.9.4 + * Copyright © 2015 Gion Kunz + * Free to use under the WTFPL license. + * http://www.wtfpl.net/ + */ + +!function(a,b){"function"==typeof define&&define.amd?define([],function(){return a.Chartist=b()}):"object"==typeof exports?module.exports=b():a.Chartist=b()}(this,function(){var a={version:"0.9.4"};return function(a,b,c){"use strict";c.noop=function(a){return a},c.alphaNumerate=function(a){return String.fromCharCode(97+a%26)},c.extend=function(a){a=a||{};var b=Array.prototype.slice.call(arguments,1);return b.forEach(function(b){for(var d in b)"object"!=typeof b[d]||null===b[d]||b[d]instanceof Array?a[d]=b[d]:a[d]=c.extend({},a[d],b[d])}),a},c.replaceAll=function(a,b,c){return a.replace(new RegExp(b,"g"),c)},c.stripUnit=function(a){return"string"==typeof a&&(a=a.replace(/[^0-9\+-\.]/g,"")),+a},c.ensureUnit=function(a,b){return"number"==typeof a&&(a+=b),a},c.querySelector=function(a){return a instanceof Node?a:b.querySelector(a)},c.times=function(a){return Array.apply(null,new Array(a))},c.sum=function(a,b){return a+(b?b:0)},c.mapMultiply=function(a){return function(b){return b*a}},c.mapAdd=function(a){return function(b){return b+a}},c.serialMap=function(a,b){var d=[],e=Math.max.apply(null,a.map(function(a){return a.length}));return c.times(e).forEach(function(c,e){var f=a.map(function(a){return a[e]});d[e]=b.apply(null,f)}),d},c.roundWithPrecision=function(a,b){var d=Math.pow(10,b||c.precision);return Math.round(a*d)/d},c.precision=8,c.escapingMap={"&":"&","<":"<",">":">",'"':""","'":"'"},c.serialize=function(a){return null===a||void 0===a?a:("number"==typeof a?a=""+a:"object"==typeof a&&(a=JSON.stringify({data:a})),Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,b,c.escapingMap[b])},a))},c.deserialize=function(a){if("string"!=typeof a)return a;a=Object.keys(c.escapingMap).reduce(function(a,b){return c.replaceAll(a,c.escapingMap[b],b)},a);try{a=JSON.parse(a),a=void 0!==a.data?a.data:a}catch(b){}return a},c.createSvg=function(a,b,d,e){var f;return b=b||"100%",d=d||"100%",Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function(a){return a.getAttributeNS("http://www.w3.org/2000/xmlns/",c.xmlNs.prefix)}).forEach(function(b){a.removeChild(b)}),f=new c.Svg("svg").attr({width:b,height:d}).addClass(e).attr({style:"width: "+b+"; height: "+d+";"}),a.appendChild(f._node),f},c.reverseData=function(a){a.labels.reverse(),a.series.reverse();for(var b=0;bf.high&&(f.high=c),h&&ck,m=e?c.rho(j.range):0;if(e&&c.projectLength(a,1,j)>=d)j.step=1;else if(e&&m=d)j.step=m;else for(;;){if(l&&c.projectLength(a,j.step,j)<=d)j.step*=2;else{if(l||!(c.projectLength(a,j.step/2,j)>=d))break;if(j.step/=2,e&&j.step%1!==0){j.step*=2;break}}if(i++>1e3)throw new Error("Exceeded maximum number of iterations while optimizing scale step!")}for(g=j.min,h=j.max;g+j.step<=j.low;)g+=j.step;for(;h-j.step>=j.high;)h-=j.step;for(j.min=g,j.max=h,j.range=j.max-j.min,j.values=[],f=j.min;f<=j.max;f+=j.step)j.values.push(c.roundWithPrecision(f));return j},c.polarToCartesian=function(a,b,c,d){var e=(d-90)*Math.PI/180;return{x:a+c*Math.cos(e),y:b+c*Math.sin(e)}},c.createChartRect=function(a,b,d){var e=!(!b.axisX&&!b.axisY),f=e?b.axisY.offset:0,g=e?b.axisX.offset:0,h=a.width()||c.stripUnit(b.width)||0,i=a.height()||c.stripUnit(b.height)||0,j=c.normalizePadding(b.chartPadding,d);h=Math.max(h,f+j.left+j.right),i=Math.max(i,g+j.top+j.bottom);var k={padding:j,width:function(){return this.x2-this.x1},height:function(){return this.y1-this.y2}};return e?("start"===b.axisX.position?(k.y2=j.top+g,k.y1=Math.max(i-j.bottom,k.y2+1)):(k.y2=j.top,k.y1=Math.max(i-j.bottom-g,k.y2+1)),"start"===b.axisY.position?(k.x1=j.left+f,k.x2=Math.max(h-j.right,k.x1+1)):(k.x1=j.left,k.x2=Math.max(h-j.right-f,k.x1+1))):(k.x1=j.left,k.x2=Math.max(h-j.right,k.x1+1),k.y2=j.top,k.y1=Math.max(i-j.bottom,k.y2+1)),k},c.createGrid=function(a,b,d,e,f,g,h,i){var j={};j[d.units.pos+"1"]=a,j[d.units.pos+"2"]=a,j[d.counterUnits.pos+"1"]=e,j[d.counterUnits.pos+"2"]=e+f;var k=g.elem("line",j,h.join(" "));i.emit("draw",c.extend({type:"grid",axis:d,index:b,group:g,element:k},j))},c.createLabel=function(a,b,d,e,f,g,h,i,j,k,l){var m,n={};if(n[f.units.pos]=a+h[f.units.pos],n[f.counterUnits.pos]=h[f.counterUnits.pos],n[f.units.len]=b,n[f.counterUnits.len]=g-10,k){var o=''+e[d]+"";m=i.foreignObject(o,c.extend({style:"overflow: visible;"},n))}else m=i.elem("text",n,j.join(" ")).text(e[d]);l.emit("draw",c.extend({type:"label",axis:f,index:d,group:i,element:m,text:e[d]},n))},c.getSeriesOption=function(a,b,c){if(a.name&&b.series&&b.series[a.name]){var d=b.series[a.name];return d.hasOwnProperty(c)?d[c]:b[c]}return b[c]},c.optionsProvider=function(b,d,e){function f(b){var f=h;if(h=c.extend({},j),d)for(i=0;i1){var i=[];return h.forEach(function(a){i.push(g(a.pathCoordinates,a.valueData))}),c.Svg.Path.join(i)}if(a=h[0].pathCoordinates,d=h[0].valueData,a.length<=4)return c.Interpolation.none()(a,d);for(var j,k=(new c.Svg.Path).move(a[0],a[1],!1,d[0]),l=0,m=a.length;m-2*!j>l;l+=2){var n=[{x:+a[l-2],y:+a[l-1]},{x:+a[l],y:+a[l+1]},{x:+a[l+2],y:+a[l+3]},{x:+a[l+4],y:+a[l+5]}];j?l?m-4===l?n[3]={x:+a[0],y:+a[1]}:m-2===l&&(n[2]={x:+a[0],y:+a[1]},n[3]={x:+a[2],y:+a[3]}):n[0]={x:+a[m-2],y:+a[m-1]}:m-4===l?n[3]=n[2]:l||(n[0]={x:+a[l],y:+a[l+1]}),k.curve(e*(-n[0].x+6*n[1].x+n[2].x)/6+f*n[2].x,e*(-n[0].y+6*n[1].y+n[2].y)/6+f*n[2].y,e*(n[1].x+6*n[2].x-n[3].x)/6+f*n[2].x,e*(n[1].y+6*n[2].y-n[3].y)/6+f*n[2].y,n[2].x,n[2].y,!1,d[(l+2)/2])}return k}},c.Interpolation.step=function(a){var b={postpone:!0};return a=c.extend({},b,a),function(b,d){for(var e=new c.Svg.Path,f=!0,g=2;g1}).map(function(a){var b=a.pathElements[0],c=a.pathElements[a.pathElements.length-1];return a.clone(!0).position(0).remove(1).move(b.x,r).line(b.x,b.y).position(a.pathElements.length+1).line(c.x,r)}).forEach(function(h){var k=i.elem("path",{d:h.stringify()},a.classNames.area,!0).attr({values:b.normalized[g]},c.xmlNs.uri);this.eventEmitter.emit("draw",{type:"area",values:b.normalized[g],path:h.clone(),series:f,seriesIndex:g,axisX:d,axisY:e,chartRect:j,index:g,group:i,element:k})}.bind(this))}}.bind(this)),this.eventEmitter.emit("created",{bounds:e.bounds,chartRect:j,axisX:d,axisY:e,svg:this.svg,options:a})}function e(a,b,d,e){c.Line["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,type:void 0,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,showLine:!0,showPoint:!0,showArea:!1,areaBase:0,lineSmooth:!0,low:void 0,high:void 0,chartPadding:{top:15,right:15,bottom:5,left:10},fullWidth:!1,reverseData:!1,classNames:{chart:"ct-chart-line",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",line:"ct-line",point:"ct-point",area:"ct-area",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Line=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a){var b,d={raw:this.data,normalized:a.distributeSeries?c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y").map(function(a){return[a]}):c.getDataArray(this.data,a.reverseData,a.horizontalBars?"x":"y")};this.svg=c.createSvg(this.container,a.width,a.height,a.classNames.chart+(a.horizontalBars?" "+a.classNames.horizontalBars:""));var e=this.svg.elem("g").addClass(a.classNames.gridGroup),g=this.svg.elem("g"),h=this.svg.elem("g").addClass(a.classNames.labelGroup);if(a.stackBars){var i=c.serialMap(d.normalized,function(){return Array.prototype.slice.call(arguments).map(function(a){return a}).reduce(function(a,b){return{x:a.x+b.x||0,y:a.y+b.y||0}},{x:0,y:0})});b=c.getHighLow([i],c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y")}else b=c.getHighLow(d.normalized,c.extend({},a,{referenceValue:0}),a.horizontalBars?"x":"y");b.high=+a.high||(0===a.high?0:b.high),b.low=+a.low||(0===a.low?0:b.low);var j,k,l,m,n,o=c.createChartRect(this.svg,a,f.padding);k=a.distributeSeries&&a.stackBars?d.raw.labels.slice(0,1):d.raw.labels,a.horizontalBars?(j=m=void 0===a.axisX.type?new c.AutoScaleAxis(c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})):a.axisX.type.call(c,c.Axis.units.x,d,o,c.extend({},a.axisX,{highLow:b,referenceValue:0})),l=n=void 0===a.axisY.type?new c.StepAxis(c.Axis.units.y,d,o,{ticks:k}):a.axisY.type.call(c,c.Axis.units.y,d,o,a.axisY)):(l=m=void 0===a.axisX.type?new c.StepAxis(c.Axis.units.x,d,o,{ticks:k}):a.axisX.type.call(c,c.Axis.units.x,d,o,a.axisX),j=n=void 0===a.axisY.type?new c.AutoScaleAxis(c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})):a.axisY.type.call(c,c.Axis.units.y,d,o,c.extend({},a.axisY,{highLow:b,referenceValue:0})));var p=a.horizontalBars?o.x1+j.projectValue(0):o.y1-j.projectValue(0),q=[];l.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),j.createGridAndLabels(e,h,this.supportsForeignObject,a,this.eventEmitter),d.raw.series.forEach(function(b,e){var f,h,i=e-(d.raw.series.length-1)/2;f=a.distributeSeries&&!a.stackBars?l.axisLength/d.normalized.length/2:a.distributeSeries&&a.stackBars?l.axisLength/2:l.axisLength/d.normalized[e].length/2,h=g.elem("g"),h.attr({"series-name":b.name,meta:c.serialize(b.meta)},c.xmlNs.uri),h.addClass([a.classNames.series,b.className||a.classNames.series+"-"+c.alphaNumerate(e)].join(" ")),d.normalized[e].forEach(function(g,k){var r,s,t,u;if(u=a.distributeSeries&&!a.stackBars?e:a.distributeSeries&&a.stackBars?0:k,r=a.horizontalBars?{x:o.x1+j.projectValue(g&&g.x?g.x:0,k,d.normalized[e]),y:o.y1-l.projectValue(g&&g.y?g.y:0,u,d.normalized[e])}:{x:o.x1+l.projectValue(g&&g.x?g.x:0,u,d.normalized[e]),y:o.y1-j.projectValue(g&&g.y?g.y:0,k,d.normalized[e])},l instanceof c.StepAxis&&(l.options.stretch||(r[l.units.pos]+=f*(a.horizontalBars?-1:1)),r[l.units.pos]+=a.stackBars||a.distributeSeries?0:i*a.seriesBarDistance*(a.horizontalBars?-1:1)),t=q[k]||p,q[k]=t-(p-r[l.counterUnits.pos]),void 0!==g){var v={};v[l.units.pos+"1"]=r[l.units.pos],v[l.units.pos+"2"]=r[l.units.pos],v[l.counterUnits.pos+"1"]=a.stackBars?t:p,v[l.counterUnits.pos+"2"]=a.stackBars?q[k]:r[l.counterUnits.pos],v.x1=Math.min(Math.max(v.x1,o.x1),o.x2),v.x2=Math.min(Math.max(v.x2,o.x1),o.x2),v.y1=Math.min(Math.max(v.y1,o.y2),o.y1),v.y2=Math.min(Math.max(v.y2,o.y2),o.y1),s=h.elem("line",v,a.classNames.bar).attr({value:[g.x,g.y].filter(function(a){return a}).join(","),meta:c.getMetaData(b,k)},c.xmlNs.uri), +this.eventEmitter.emit("draw",c.extend({type:"bar",value:g,index:k,meta:c.getMetaData(b,k),series:b,seriesIndex:e,axisX:m,axisY:n,chartRect:o,group:h,element:s},v))}}.bind(this))}.bind(this)),this.eventEmitter.emit("created",{bounds:j.bounds,chartRect:o,axisX:m,axisY:n,svg:this.svg,options:a})}function e(a,b,d,e){c.Bar["super"].constructor.call(this,a,b,f,c.extend({},f,d),e)}var f={axisX:{offset:30,position:"end",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:30,onlyInteger:!1},axisY:{offset:40,position:"start",labelOffset:{x:0,y:0},showLabel:!0,showGrid:!0,labelInterpolationFnc:c.noop,scaleMinSpace:20,onlyInteger:!1},width:void 0,height:void 0,high:void 0,low:void 0,onlyInteger:!1,chartPadding:{top:15,right:15,bottom:5,left:10},seriesBarDistance:15,stackBars:!1,horizontalBars:!1,distributeSeries:!1,reverseData:!1,classNames:{chart:"ct-chart-bar",horizontalBars:"ct-horizontal-bars",label:"ct-label",labelGroup:"ct-labels",series:"ct-series",bar:"ct-bar",grid:"ct-grid",gridGroup:"ct-grids",vertical:"ct-vertical",horizontal:"ct-horizontal",start:"ct-start",end:"ct-end"}};c.Bar=c.Base.extend({constructor:e,createChart:d})}(window,document,a),function(a,b,c){"use strict";function d(a,b,c){var d=b.x>a.x;return d&&"explode"===c||!d&&"implode"===c?"start":d&&"implode"===c||!d&&"explode"===c?"end":"middle"}function e(a){var b,e,f,h,i,j=[],k=a.startAngle,l=c.getDataArray(this.data,a.reverseData);this.svg=c.createSvg(this.container,a.width,a.height,a.donut?a.classNames.chartDonut:a.classNames.chartPie),e=c.createChartRect(this.svg,a,g.padding),f=Math.min(e.width()/2,e.height()/2),i=a.total||l.reduce(function(a,b){return a+b},0),f-=a.donut?a.donutWidth/2:0,h="outside"===a.labelPosition||a.donut?f:"center"===a.labelPosition?0:f/2,h+=a.labelOffset;var m={x:e.x1+e.width()/2,y:e.y2+e.height()/2},n=1===this.data.series.filter(function(a){return a.hasOwnProperty("value")?0!==a.value:0!==a}).length;a.showLabel&&(b=this.svg.elem("g",null,null,!0));for(var o=0;o180,0,r.x,r.y);a.donut||t.line(m.x,m.y);var u=j[o].elem("path",{d:t.stringify()},a.donut?a.classNames.sliceDonut:a.classNames.slicePie);if(u.attr({value:l[o],meta:c.serialize(p.meta)},c.xmlNs.uri),a.donut&&u.attr({style:"stroke-width: "+ +a.donutWidth+"px"}),this.eventEmitter.emit("draw",{type:"slice",value:l[o],totalDataSum:i,index:o,meta:p.meta,series:p,group:j[o],element:u,path:t.clone(),center:m,radius:f,startAngle:k,endAngle:q}),a.showLabel){var v=c.polarToCartesian(m.x,m.y,h,k+(q-k)/2),w=a.labelInterpolationFnc(this.data.labels?this.data.labels[o]:l[o],o);if(w||0===w){var x=b.elem("text",{dx:v.x,dy:v.y,"text-anchor":d(m,v,a.labelDirection)},a.classNames.label).text(""+w);this.eventEmitter.emit("draw",{type:"label",index:o,group:b,element:x,text:""+w,x:v.x,y:v.y})}}k=q}this.eventEmitter.emit("created",{chartRect:e,svg:this.svg,options:a})}function f(a,b,d,e){c.Pie["super"].constructor.call(this,a,b,g,c.extend({},g,d),e)}var g={width:void 0,height:void 0,chartPadding:5,classNames:{chartPie:"ct-chart-pie",chartDonut:"ct-chart-donut",series:"ct-series",slicePie:"ct-slice-pie",sliceDonut:"ct-slice-donut",label:"ct-label"},startAngle:0,total:void 0,donut:!1,donutWidth:60,showLabel:!0,labelOffset:0,labelPosition:"inside",labelInterpolationFnc:c.noop,labelDirection:"neutral",reverseData:!1};c.Pie=c.Base.extend({constructor:f,createChart:e,determineAnchorPosition:d})}(window,document,a),a}); +//# sourceMappingURL=chartist.min.js.map \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/demo.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/demo.js new file mode 100644 index 0000000..b4bb5ee --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/demo.js @@ -0,0 +1,152 @@ +type = ['','info','success','warning','danger']; + + +demo = { + initPickColor: function(){ + $('.pick-class-label').click(function(){ + var new_class = $(this).attr('new-class'); + var old_class = $('#display-buttons').attr('data-class'); + var display_div = $('#display-buttons'); + if(display_div.length) { + var display_buttons = display_div.find('.btn'); + display_buttons.removeClass(old_class); + display_buttons.addClass(new_class); + display_div.attr('data-class', new_class); + } + }); + }, + + initChartist: function(){ + + var dataSales = { + labels: ['9:00AM', '12:00AM', '3:00PM', '6:00PM', '9:00PM', '12:00PM', '3:00AM', '6:00AM'], + series: [ + [287, 385, 490, 492, 554, 586, 698, 695, 752, 788, 846, 944], + [67, 152, 143, 240, 287, 335, 435, 437, 539, 542, 544, 647], + [23, 113, 67, 108, 190, 239, 307, 308, 439, 410, 410, 509] + ] + }; + + var optionsSales = { + lineSmooth: false, + low: 0, + high: 800, + showArea: true, + height: "245px", + axisX: { + showGrid: false, + }, + lineSmooth: Chartist.Interpolation.simple({ + divisor: 3 + }), + showLine: false, + showPoint: false, + }; + + var responsiveSales = [ + ['screen and (max-width: 640px)', { + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Line('#chartHours', dataSales, optionsSales, responsiveSales); + + + var data = { + labels: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + series: [ + [542, 443, 320, 780, 553, 453, 326, 434, 568, 610, 756, 895], + [412, 243, 280, 580, 453, 353, 300, 364, 368, 410, 636, 695] + ] + }; + + var options = { + seriesBarDistance: 10, + axisX: { + showGrid: false + }, + height: "245px" + }; + + var responsiveOptions = [ + ['screen and (max-width: 640px)', { + seriesBarDistance: 5, + axisX: { + labelInterpolationFnc: function (value) { + return value[0]; + } + } + }] + ]; + + Chartist.Bar('#chartActivity', data, options, responsiveOptions); + + var dataPreferences = { + series: [ + [25, 30, 20, 25] + ] + }; + + var optionsPreferences = { + donut: true, + donutWidth: 40, + startAngle: 0, + total: 100, + showLabel: false, + axisX: { + showGrid: false + } + }; + + Chartist.Pie('#chartPreferences', dataPreferences, optionsPreferences); + + Chartist.Pie('#chartPreferences', { + labels: ['62%','32%','6%'], + series: [62, 32, 6] + }); + }, + + initGoogleMaps: function(){ + var myLatlng = new google.maps.LatLng(40.748817, -73.985428); + var mapOptions = { + zoom: 13, + center: myLatlng, + scrollwheel: false, //we disable de scroll over the map, it is a really annoing when you scroll through page + styles: [{"featureType":"water","stylers":[{"saturation":43},{"lightness":-11},{"hue":"#0088ff"}]},{"featureType":"road","elementType":"geometry.fill","stylers":[{"hue":"#ff0000"},{"saturation":-100},{"lightness":99}]},{"featureType":"road","elementType":"geometry.stroke","stylers":[{"color":"#808080"},{"lightness":54}]},{"featureType":"landscape.man_made","elementType":"geometry.fill","stylers":[{"color":"#ece2d9"}]},{"featureType":"poi.park","elementType":"geometry.fill","stylers":[{"color":"#ccdca1"}]},{"featureType":"road","elementType":"labels.text.fill","stylers":[{"color":"#767676"}]},{"featureType":"road","elementType":"labels.text.stroke","stylers":[{"color":"#ffffff"}]},{"featureType":"poi","stylers":[{"visibility":"off"}]},{"featureType":"landscape.natural","elementType":"geometry.fill","stylers":[{"visibility":"on"},{"color":"#b8cb93"}]},{"featureType":"poi.park","stylers":[{"visibility":"on"}]},{"featureType":"poi.sports_complex","stylers":[{"visibility":"on"}]},{"featureType":"poi.medical","stylers":[{"visibility":"on"}]},{"featureType":"poi.business","stylers":[{"visibility":"simplified"}]}] + + } + var map = new google.maps.Map(document.getElementById("map"), mapOptions); + + var marker = new google.maps.Marker({ + position: myLatlng, + title:"Hello World!" + }); + + // To add the marker to the map, call setMap(); + marker.setMap(map); + }, + + showNotification: function(from, align){ + color = Math.floor((Math.random() * 4) + 1); + + $.notify({ + icon: "pe-7s-gift", + message: "Welcome to Light Bootstrap Dashboard - a beautiful freebie for every web developer." + + },{ + type: type[color], + timer: 4000, + placement: { + from: from, + align: align + } + }); + } + + +} + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/jquery-1.10.2.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/jquery-1.10.2.js new file mode 100644 index 0000000..d6f6ac8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/html/assets/js/jquery-1.10.2.js @@ -0,0 +1,9789 @@ +/*! + * jQuery JavaScript Library v1.10.2 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03T13:48Z + */ +(function( window, undefined ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +//"use strict"; +var + // The deferred used on DOM ready + readyList, + + // A central reference to the root jQuery(document) + rootjQuery, + + // Support: IE<10 + // For `typeof xmlNode.method` instead of `xmlNode.method !== undefined` + core_strundefined = typeof undefined, + + // Use the correct document accordingly with window argument (sandbox) + location = window.location, + document = window.document, + docElem = document.documentElement, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // [[Class]] -> type pairs + class2type = {}, + + // List of deleted data cache ids, so we can reuse them + core_deletedIds = [], + + core_version = "1.10.2", + + // Save a reference to some core methods + core_concat = core_deletedIds.concat, + core_push = core_deletedIds.push, + core_slice = core_deletedIds.slice, + core_indexOf = core_deletedIds.indexOf, + core_toString = class2type.toString, + core_hasOwn = class2type.hasOwnProperty, + core_trim = core_version.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + + // Used for splitting on whitespace + core_rnotwhite = /\S+/g, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + + // The ready event handler + completed = function( event ) { + + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } + }, + // Clean-up method for dom ready events + detach = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: core_version, + + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), + + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + if ( obj == null ) { + return String( obj ); + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ core_toString.call(obj) ] || "object" : + typeof obj; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( jQuery.support.ownLast ) { + for ( key in obj ) { + return core_hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // keepScripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + if ( scripts ) { + jQuery( scripts ).remove(); + } + return jQuery.merge( [], parsed.childNodes ); + }, + + parseJSON: function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + if ( data === null ) { + return data; + } + + if ( typeof data === "string" ) { + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + if ( data ) { + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + } + } + } + + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + core_push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return core_concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations. + // Note: this method belongs to the css module but it's needed here for the support module. + // If support gets modularized, this method should be moved back to the css module. + swap: function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + var length = obj.length, + type = jQuery.type( obj ); + + if ( jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || type !== "function" && + ( length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj ); +} + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +/*! + * Sizzle CSS Selector Engine v1.10.2 + * http://sizzlejs.com/ + * + * Copyright 2013 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2013-07-03 + */ +(function( window, undefined ) { + +var i, + support, + cachedruns, + Expr, + getText, + isXML, + compile, + outermostContext, + sortInput, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + -(new Date()), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + hasDuplicate = false, + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + return 0; + }, + + // General-purpose constants + strundefined = typeof undefined, + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf if we can't use a native one + indexOf = arr.indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:([*^$|!~]?=)" + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments quoted, + // then not containing pseudos/brackets, + // then attribute selectors/non-parenthetical expressions, + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rsibling = new RegExp( whitespace + "*[+~]" ), + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + // BMP codepoint + high < 0 ? + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { + return []; + } + + if ( documentIsHTML && !seed ) { + + // Shortcuts + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key += " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Detect xml + * @param {Element|Object} elem An element or a document + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var doc = node ? node.ownerDocument || node : preferredDoc, + parent = doc.defaultView; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + + // Support tests + documentIsHTML = !isXML( doc ); + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent.attachEvent && parent !== parent.top ) { + parent.attachEvent( "onbeforeunload", function() { + setDocument(); + }); + } + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Check if getElementsByClassName can be trusted + support.getElementsByClassName = assert(function( div ) { + div.innerHTML = "
    "; + + // Support: Safari<4 + // Catch class over-caching + div.firstChild.className = "i"; + // Support: Opera<10 + // Catch gEBCN failure to find non-leading classes + return div.getElementsByClassName("i").length === 2; + }); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== strundefined && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var elem, + tmp = [], + i = 0, + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Support: Opera 10-12/IE8 + // ^= $= *= and empty values + // Should not select anything + // Support: Windows 8 Native Apps + // The type attribute is restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "t", "" ); + + if ( div.querySelectorAll("[t^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b ); + + if ( compare ) { + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } + + // Not directly comparable, sort on existence of method + return a.compareDocumentPosition ? -1 : 1; + } : + function( a, b ) { + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Parentless nodes are either documents or disconnected + } else if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, document, null, [elem] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val === undefined ? + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null : + val; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[5] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] && match[4] !== undefined ) { + match[2] = match[4]; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var data, cache, outerCache, + dirkey = dirruns + " " + doneName; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) { + if ( (data = cache[1]) === true || data === cachedruns ) { + return data === true; + } + } else { + cache = outerCache[ dir ] = [ dirkey ]; + cache[1] = matcher( elem, context, xml ) || cachedruns; + if ( cache[1] === true ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + // A counter to specify which element is currently being matched + var matcherCachedRuns = 0, + bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = matcherCachedRuns; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++matcherCachedRuns; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed ) { + var i, tokens, token, type, find, + match = tokenize( selector ); + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + } + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && context.parentNode || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) + ); + return results; +} + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome<14 +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = ""; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = ""; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + elem[ name ] === true ? name.toLowerCase() : null; + } + }); +} + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function( support ) { + + var all, a, input, select, fragment, opt, eventName, isSupported, i, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
    a"; + + // Finish early in limited (non-browser) environments + all = div.getElementsByTagName("*") || []; + a = div.getElementsByTagName("a")[ 0 ]; + if ( !a || !a.style || !all.length ) { + return support; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName("tbody").length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName("link").length; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + support.opacity = /^0.5/.test( a.style.opacity ); + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!a.style.cssFloat; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>"; + + // Will be defined later + support.inlineBlockNeedsLayout = false; + support.shrinkWrapBlocks = false; + support.pixelPosition = false; + support.deleteExpando = true; + support.noCloneEvent = true; + support.reliableMarginRight = true; + support.boxSizingReliable = true; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE<9 + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + // Check if we can trust getAttribute("value") + input = document.createElement("input"); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "checked", "t" ); + input.setAttribute( "name", "t" ); + + fragment = document.createDocumentFragment(); + fragment.appendChild( input ); + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event) + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + for ( i in { submit: true, change: true, focusin: true }) { + div.setAttribute( eventName = "on" + i, "t" ); + + support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false; + } + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: IE<9 + // Iteration over object's inherited properties before its own. + for ( i in jQuery( support ) ) { + break; + } + support.ownLast = i !== "0"; + + // Run tests that need a body at doc ready + jQuery(function() { + var container, marginDiv, tds, + divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px"; + + body.appendChild( container ).appendChild( div ); + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "
    t
    "; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Support: IE8 + // Check if empty table cells still have offsetWidth/Height + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior. + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + + // Workaround failing boxSizing test due to offsetWidth returning wrong value + // with some non-1 values of body zoom, ticket #13543 + jQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() { + support.boxSizing = div.offsetWidth === 4; + }); + + // Use window.getComputedStyle because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. (#3333) + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = div.appendChild( document.createElement("div") ); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== core_strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + div.style.display = "block"; + div.innerHTML = "
    "; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + if ( support.inlineBlockNeedsLayout ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); + + // Null elements to avoid leaks in IE + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + all = select = fragment = opt = a = input = null; + + return support; +})({}); + +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +function internalData( elem, name, data, pvt /* Internal Use Only */ ){ + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "applet": true, + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + // Do not set data on non-element because it will not be cleared (#8335). + if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) { + return false; + } + + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var attrs, name, + data = null, + i = 0, + elem = this[0]; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attrs = elem.attributes; + for ( ; i < attrs.length; i++ ) { + name = attrs[i].name; + + if ( name.indexOf("data-") === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, + rclass = /[\t\r\n\f]/g, + rreturn = /\r/g, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, + getSetInput = jQuery.support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + elem.className = jQuery.trim( cur ); + + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + elem.className = value ? jQuery.trim( cur ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( core_rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === core_strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var ret, hooks, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // Use proper attribute retrieval(#6932, #12072) + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + if ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) { + optionSet = true; + } + } + + // force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === core_strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( core_rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + }, + + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Hooks for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr; + + jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var fn = jQuery.expr.attrHandle[ name ], + ret = isXML ? + undefined : + /* jshint eqeqeq: false */ + (jQuery.expr.attrHandle[ name ] = undefined) != + getter( elem, name, isXML ) ? + + name.toLowerCase() : + null; + jQuery.expr.attrHandle[ name ] = fn; + return ret; + } : + function( elem, name, isXML ) { + return isXML ? + undefined : + elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + return name === "value" || value === elem.getAttribute( name ) ? + value : + undefined; + } + }; + jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords = + // Some attributes are constructed with empty-string values when not defined + function( elem, name, isXML ) { + var ret; + return isXML ? + undefined : + (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + }; + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + return ret && ret.specified ? + ret.value : + undefined; + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !jQuery.support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !jQuery.support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( core_rnotwhite ) || [""]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = core_hasOwn.call( event, "type" ) ? event.type : event, + namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = core_slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === core_strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); +var isSimple = /^.[^:#\[\.,]*$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + cur = ret.push( cur ); + break; + } + } + } + + return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( jQuery.unique(all) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( isSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
    ", "
    " ], + area: [ 1, "", "" ], + param: [ 1, "", "" ], + thead: [ 1, "", "
    " ], + tr: [ 2, "", "
    " ], + col: [ 2, "", "
    " ], + td: [ 3, "", "
    " ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
    ", "
    " ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var + // Snapshot the DOM in case .domManip sweeps something relevant into its fragment + args = jQuery.map( this, function( elem ) { + return [ elem.nextSibling, elem.parentNode ]; + }), + i = 0; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + var next = args[ i++ ], + parent = args[ i++ ]; + + if ( parent ) { + // Don't use the snapshot next if it has moved (#13810) + if ( next && next.parentNode !== parent ) { + next = this.nextSibling; + } + jQuery( this ).remove(); + parent.insertBefore( elem, next ); + } + // Allow new content to include elements from the context set + }, true ); + + // Force removal if there was no new content (e.g., from empty arguments) + return i ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback, allowIntersection ) { + + // Flatten any nested arrays + args = core_concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback, allowIntersection ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Hope ajax is available... + jQuery._evalUrl( node.src ); + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && manipulation_rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + core_push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( manipulation_rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare or + wrap[1] === "
    " && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== core_strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + core_deletedIds.push( id ); + } + } + } + } + }, + + _evalUrl: function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } +}); +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); +var iframe, getStyles, curCSS, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + + if ( !values[ index ] ) { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + var len, styles, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +// NOTE: we've included the "window" in window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, _computed ) { + var width, minWidth, maxWidth, + computed = _computed || getStyles( elem ), + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined, + style = elem.style; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, _computed ) { + var left, rs, rsLeft, + computed = _computed || getStyles( elem ), + ret = computed ? computed[ name ] : undefined, + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + // Use the already-created iframe if possible + iframe = ( iframe || + jQuery(" + + + + + + + + + + + + + + +
    + + + +
    + + + + + +
    + + + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donutchartssimple.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donutchartssimple.html new file mode 100644 index 0000000..0a415aa --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/donutchartssimple.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + +
    + + + +
    + + + +
    + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/README.md b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/README.md new file mode 100644 index 0000000..034bf28 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/README.md @@ -0,0 +1,109 @@ +# [Light Bootstrap Dashboard](http://www.creative-tim.com/product/light-bootstrap-dashboard) + +Light Bootstrap Dashboard is an admin dashboard template designed to be beautiful and simple. It is built on top of Bootstrap 3 and it is fully responsive. It comes with a big collections of elements that will offer you multiple possibilities to create the app that best fits your needs. It can be used to create admin panels, project management systems, web applications backend, CMS or CRM. + +The product represents a big suite of front-end developer tools that can help you jump start your project. We have created it thinking about things you actually need in a dashboard. Light Bootstrap Dashboard contains multiple handpicked and optimised plugins. Everything is designed to fit with one another. As you will be able to see, the dashboard you can access on Creative Tim is a customisation of this product. + +It comes with 6 filter colors for the sidebar (“black”, “azure”,”green”,”orange”,”red”,”purple”) and an option to have a background image. + +Special thanks go to: +Robert McIntosh for the notification system +Chartist for the wonderful charts +We are very excited to share this dashboard with you and we look forward to hearing your feedback! + +## Links: + ++ [Live Preview](http://demos.creative-tim.com/light-bootstrap-dashboard) ++ [Video Tutorial](https://www.youtube.com/watch?v=c3M3NQtFyqM) ++ [Light Bootstrap Dashboard PRO](http://www.creative-tim.com/product/light-bootstrap-dashboard-pro) (from $39) + +## Quick start + +Quick start options: + +- [Download from Github](https://github.com/timcreative/light-bootstrap-dashboard/releases/tag/v1.3). +- [Download from Creative Tim](http://www.creative-tim.com/product/light-bootstrap-dashboard). +- Clone the repo: `git clone https://github.com/timcreative/light-bootstrap-dashboard.git`. + + +### What's included + +Within the download you'll find the following directories and files: + +``` +x_lbd_free/ +├── assets/ +| ├── css/ +| | ├── animate.min.css +| | ├── bootstrap.min.css +| | ├── demo.css +│ | ├── light-bootstrap-dashboard.css +│ | └── pe-icon-7-stroke.css +| ├── js/ +| | ├── bootstrap-checkbox-radio-switch.js +| | ├── bootstrap-notify.js +| | ├── bootstrap-select.js +| | ├── bootstrap.min.js +│ | ├── chartist.min.js +│ | ├── demo.js +│ | ├── jquery-1.10.2.js +│ | └── light-bootstrap-dashboard.js +| ├── fonts/ +| | ├── Pe-icon-7-stroke.eot +| | ├── Pe-icon-7-stroke.svg +| | ├── Pe-icon-7-stroke.ttf +| | └── Pe-icon-7-stroke.woff +| └── img/ +| +├── Creative Tim License.pdf +├── dashboard.html +├── icons.html +├── maps.html +├── notifications.html +├── table.html +├── template.html +├── typography.html +├── upgrade.html +└── user.html + +``` + +### Version logs + +V1.0 - 20 August 2015 initial release + +V1.1 - 08 September 2015 - bug fixing [current version] +- added company name/logo inside the sidebar for small screens +- fixed bug for notification with close button on small screens +- fix live preview bug for download on small screens +- fix table responsive for small screens +- added new labels for chartist on small screens + +V1.2 - 17 January 2016 - New Page +- for those who want to upsell inside their dashboard we added a new page "Upgrade to PRO" with a pricing and options table + +V1.3 - 22 January 2016 - New Template page + Video Tutorial [current version] +- added the default template page + youtube video tutorial on how to create an Admin Template (link coming soon) + + +## Useful Links + +More products from Creative Tim: + +Tutorials: + +Freebies: + +Affiliate Program (earn money): + +Social Media: + +Twitter: + +Facebook: + +Dribbble: + +Google+: + +Instagram: diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/dashboard.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/dashboard.html new file mode 100644 index 0000000..2cfb0a5 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/dashboard.html @@ -0,0 +1,334 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/graphs.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/graphs.html new file mode 100644 index 0000000..82b17e1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/graphs.html @@ -0,0 +1,263 @@ + + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + +
    +
    +
    +
    +

    CodeMR Software Graphs

    +

    Click on the titles below to enlarge graphs

    + +
    + +
    + +
    + + +
    + +
    + +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/metricdescriptions.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/metricdescriptions.html new file mode 100644 index 0000000..33edec1 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/metricdescriptions.html @@ -0,0 +1,261 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + +
    +
    +
    +
    +
    +
    +

    Object-Oriented Metric Descriptions

    +

    Informative only

    +
    + +
    + + +
    +
    +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/notifications.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/notifications.html new file mode 100644 index 0000000..992a966 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/notifications.html @@ -0,0 +1,310 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    +
    +

    Notifications

    +

    Handcrafted by our friend Robert McIntosh. Please checkout the full documentation.

    + +
    +
    +
    +
    +
    Notifications Style
    +
    + This is a plain notification +
    +
    + + This is a notification with close button. +
    +
    + + + This is a notification with close button and icon. +
    +
    + + + This is a notification with close button and icon and have many lines. You can see that the icon and the close button are always vertically aligned. This is a beautiful notification. So you don't have to worry about the style. +
    +
    +
    +
    Notification states
    +
    + + Info - This is a regular notification made with ".alert-info" +
    +
    + + Success - This is a regular notification made with ".alert-success" +
    +
    + + Warning - This is a regular notification made with ".alert-warning" +
    +
    + + Danger - This is a regular notification made with ".alert-danger" +
    +
    +
    +
    +
    +
    +
    +
    +
    Notifications Places +

    Click to view notifications

    +
    +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + +
    +
    + +
    +
    +
    +
    +
    +
    +
    + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/table.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/table.html new file mode 100644 index 0000000..5c75a2f --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/table.html @@ -0,0 +1,446 @@ + + + + + + + + CodeMR Code Quality Analysis Dashboard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    + +
    +
    +

    Detailed metric tables

    + +
    +
    +
    +
    + +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    + + + + + + +
    +
    +
    +
    +
    + +
    +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    +
    +
    +
    + +

    + +

    + +
    +
    + + + +
    + +
    +
    +
    + + + + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/template.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/template.html new file mode 100644 index 0000000..16473f6 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/lbd/template.html @@ -0,0 +1,154 @@ + + + + + + + + Light Bootstrap Dashboard by Creative Tim + + + + + + + + + + + + + + + + + + + + + + + + + +
    + + +
    + + + +
    +
    +
    + +
    +
    +
    + + + + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartmethod.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartmethod.html new file mode 100644 index 0000000..ea3a354 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartmethod.html @@ -0,0 +1,27 @@ + + + + + + + + +
    + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartpackage.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartpackage.html new file mode 100644 index 0000000..3fc0a87 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartpackage.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartx.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartx.html new file mode 100644 index 0000000..e1f67c8 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/metricchartx.html @@ -0,0 +1,25 @@ + + + + + + + + +
    + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/defaultclassmetrics.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/defaultclassmetrics.js new file mode 100644 index 0000000..3b6255c --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/defaultclassmetrics.js @@ -0,0 +1,127 @@ +// [min, t1, t2, t3, t4, max]; max for upper bound of bar scale +// 0 1 2 3 4 5 +//Ex.: 0 10 15 40 70 100 +var classMetricSpec= [ +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 50, 300, 900, 1500, 2000]}, +{shortname: "NOM", name: "Number of Methods",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "NOF", name: "Number of Fields",thresholds:[0, 20, 30, 40, 50, 60]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 20, 50, 101, 120, 150]}, +{shortname: "RFC", name: "Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "SRFC", name: "Simple Response For a Class",thresholds:[0, 50, 100, 150, 200, 250]}, +{shortname: "DIT", name: "Depth of Inheritance Tree",thresholds:[0, 1, 3, 10, 20, 30]}, +{shortname: "CBO", name: "Coupling Between Object Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "ATFD", name: "Access to Foreign Data",thresholds:[0, 1, 3, 5, 10, 20]}, +{shortname: "SI", name: "Specialization Index",thresholds:[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]}, +{shortname: "LCAM", name: "Lack of Cohesion Among Methods(1-CAM)",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "NOC", name: "Number of Children",thresholds:[0, 1, 5, 10, 15, 20]}, +{shortname: "LTCC", name: "Lack of Tight Class Cohesion",thresholds:[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]}, +{shortname: "LCOM", name: "Lack of Cohesion of Methods",thresholds:[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var classMetricValues= [ +{name: "Class Lines of Code", value:300}, +{name: "Number of Methods", value:30}, +{name: "Number of Fields", value:30}, +{name: "Weighted Method Count", value:50}, +{name: "Response For a Class", value:100}, +{name: "Simple Response For a Class", value:100}, +{name: "Depth of Inheritance Tree", value:3}, +{name: "Coupling Between Object Classes", value:10}, +{name: "Access to Foreign Data", value:3}, +{name: "Specialization Index", value:0.3}, +{name: "Lack of Cohesion Among Methods(1-CAM)", value:0.7}, +{name: "Number of Children", value:5}, +{name: "Lack of Tight Class Cohesion", value:0.7}, +{name: "Lack of Cohesion of Methods", value:0.7}, +{name: "Coverage", value:60}]; + +var packageMetricSpec= [ +{shortname: "#(C&I)", name: "Number of Entities",thresholds:[0, 5, 10, 30, 40, 50]}, +{shortname: "#C", name: "Number of Classes",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "#I", name: "Number of Interfaces",thresholds:[0, 5, 10, 20, 30, 50]}, +{shortname: "LOC", name: "Class Lines of Code",thresholds:[0, 250, 1500, 4500, 7500, 10000]}, +{shortname: "AC", name: "Afferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "EC", name: "Efferent Coupling",thresholds:[0, 5, 10, 20, 100, 150]}, +{shortname: "Abs", name: "Abstractness",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "Ins", name: "Instability",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "ND", name: "Normalized Distance",thresholds:[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]}, +{shortname: "WMC", name: "Weighted Method Count",thresholds:[0, 200, 500, 1000, 2000, 2000]}, +{shortname: "Coverage", name: "Coverage",thresholds:[0, 20, 60, 80, 90, 100]}]; + +var packageMetricValues= [ +{name: "Number of Entities", value:10}, +{name: "Number of Classes", value:10}, +{name: "Number of Interfaces", value:10}, +{name: "Class Lines of Code", value:1500}, +{name: "Afferent Coupling", value:10}, +{name: "Efferent Coupling", value:10}, +{name: "Abstractness", value:0.2}, +{name: "Instability", value:0.2}, +{name: "Normalized Distance", value:0.2}, +{name: "Weighted Method Count", value:500}, +{name: "Coverage", value:60}]; + +var methodMetricSpec= [ +{shortname: "MCC", name: "McCabe Cyclomatic Complexity",thresholds:[0, 10, 17, 20, 25, 30]}, +{shortname: "NBD", name: "Nested Block Depth",thresholds:[0, 1, 2, 4, 5, 10]}, +{shortname: "LOC", name: "Method Lines of Code",thresholds:[0, 30, 50, 100, 200, 300]}, +{shortname: "#Pa", name: "Number of Parameters",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#MC", name: "Number of Methods Called",thresholds:[0, 3, 5, 6, 8, 10]}, +{shortname: "#AF", name: "Number of Accessed Fields",thresholds:[0, 3, 5, 6, 8, 10]}]; + +var methodMetricValues= [ +{name: "McCabe Cyclomatic Complexity", value:17}, +{name: "Nested Block Depth", value:2}, +{name: "Method Lines of Code", value:50}, +{name: "Number of Parameters", value:5}, +{name: "Number of Methods Called", value:5}, +{name: "Number of Accessed Fields", value:5}]; + +//use class metrics by default; +var metricSpec = classMetricSpec; +var metricValues = classMetricValues; +var classMetricThresholds = [];classMetricThresholds["Number of Fields"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Depth of Inheritance Tree"]=[0, 1, 3, 10, 20, 30]; +classMetricThresholds["Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Lack of Tight Class Cohesion"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Lack of Cohesion of Methods"]=[0.0, 0.5, 0.7, 0.8, 1.0, 2.0]; +classMetricThresholds["Class Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Static Fields"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["Lack of Cohesion Among Methods(1-CAM)"]=[0.0, 0.6, 0.7, 0.8, 0.9, 1.0]; +classMetricThresholds["Simple Response For a Class"]=[0, 50, 100, 150, 200, 250]; +classMetricThresholds["Number of Static Methods"]=[0, 20, 30, 40, 50, 50]; +classMetricThresholds["CBO Lib"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Coupling Between Object Classes"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Access to Foreign Data"]=[0, 1, 3, 5, 10, 20]; +classMetricThresholds["Specialization Index"]=[0.0, 0.1, 0.3, 0.4, 0.7, 1.2]; +classMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +classMetricThresholds["Class-Methods Lines of Code"]=[0, 50, 300, 900, 1500, 2000]; +classMetricThresholds["Number of Children"]=[0, 1, 5, 10, 15, 20]; +classMetricThresholds["Number of Methods"]=[0, 20, 30, 40, 50, 60]; +classMetricThresholds["Number of Overridden Methods"]=[0, 5, 10, 20, 30, 40]; +classMetricThresholds["CBO App"]=[0, 5, 10, 20, 30, 50]; +classMetricThresholds["Weighted Method Count"]=[0, 20, 50, 101, 120, 150]; +var methodMetricThresholds = [];methodMetricThresholds["McCabe Cyclomatic Complexity"]=[0, 10, 17, 20, 25, 30]; +methodMetricThresholds["Nested Block Depth"]=[0, 1, 2, 4, 5, 10]; +methodMetricThresholds["Number of Methods Called"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Parameters"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Number of Accessed Fields"]=[0, 3, 5, 6, 8, 10]; +methodMetricThresholds["Method Lines of Code"]=[0, 30, 50, 100, 200, 300]; +var packageMetricThresholds = [];packageMetricThresholds["Efferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Number of Interfaces"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Number of Classes"]=[0, 5, 10, 20, 30, 50]; +packageMetricThresholds["Coverage"]=[0, 20, 60, 80, 90, 100]; +packageMetricThresholds["Normalized Distance"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Number of Entities"]=[0, 5, 10, 30, 40, 50]; +packageMetricThresholds["Abstractness"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Class Lines of Code"]=[0, 250, 1500, 4500, 7500, 10000]; +packageMetricThresholds["Instability"]=[0.0, 0.1, 0.2, 0.3, 0.4, 1.0]; +packageMetricThresholds["Afferent Coupling"]=[0, 5, 10, 20, 100, 150]; +packageMetricThresholds["Weighted Method Count"]=[0, 200, 500, 1000, 2000, 2000]; +var projectMetricThresholds = [];projectMetricThresholds["Number of Highly Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Number of Entities"]=[0, 100, 200, 300, 400, 500]; +projectMetricThresholds["Number of Problematic Classes"]=[0, 10, 100, 200, 300, 400]; +projectMetricThresholds["Class Lines of Code"]=[0, 1000, 10000, 100000, 1000000, 1100000]; +projectMetricThresholds["Number of External Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of Packages"]=[0, 10, 20, 30, 40, 50]; +projectMetricThresholds["Number of External Entities"]=[0, 100, 200, 300, 400, 500]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/overview_metric_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/overview_metric_data.js new file mode 100644 index 0000000..c477999 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/overview_metric_data.js @@ -0,0 +1 @@ +var CodeMR_ProjectMetrics = {"Project Name":"serialx-core", "Number of Highly Problematic Classes":0, "Number of Entities":30, "Number of Problematic Classes":4, "Class Lines of Code":2342, "Number of External Packages":9, "Number of Packages":5, "Number of External Entities":371} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/packagedependency.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/packagedependency.js new file mode 100644 index 0000000..edfbc0d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/packagedependency.js @@ -0,0 +1,17 @@ +var matrix = [[0,1,8,1,1],[0,0,2,2,0],[1,0,0,1,0],[3,3,3,0,0],[0,0,0,0,0]] +var packages = [{ +"name": " org.ugp.serialx.converters", "color": " #3182bd" +} +,{ +"name": " org.ugp.serialx.protocols", "color": " #6baed6" +} +,{ +"name": " org.ugp.serialx.utils", "color": " #9ecae1" +} +,{ +"name": " org.ugp.serialx", "color": " #c6dbef" +} +,{ +"name": " org.ugp.serialx.converters.imports", "color": " #e6550d" +} +]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/summary_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/summary_data.js new file mode 100644 index 0000000..f00b487 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/summary_data.js @@ -0,0 +1,6 @@ +var EQ_summaryInfo = [ +{label:"high coupling, high complexity, low cohesion", color: "#E50000", value: 0,count:0}, +{label:"high coupling, high complexity", color: "#FF5B13", value: 0,count:0}, +{label:"high coupling", color: "#FFC800", value: 0,count:0}, +{label:"high complexity", color: "#62BF18", value: 898,count:3}, +{label:"fair quality attributes", color: "#007F24", value: 1663,count:27}]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/sunburst_data.js new file mode 100644 index 0000000..b7afcf4 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/sunburst_data.js @@ -0,0 +1,231 @@ +function EQ_GET_DATA(){ + var ret = { +"name": " serialx-core", "value":2342, +"prmetrics":{"5":1,"6":1,"7":1,"8":2,"9":1,"10":1,"11":4}, +"prmetricvalues":{"5":0,"6":30,"7":4,"8":2342,"9":9,"10":5,"11":371}, +"children": [ { +"name": "org.ugp.serialx.converters", "value":571, +"pmetrics":{"4":3,"12":2,"13":1,"14":2,"3":1,"1":2,"0":2,"6":3,"8":2,"2":2,"15":1,"16":2}, +"pmetricvalues":{"4":3,"12":8,"13":2,"14":10,"3":1,"1":2,"0":2,"17":0.166,"6":12,"18":0.167,"8":571,"19":0.667,"2":2,"15":4,"16":288}, +"children":[ +{ +"name": "ProtocolConverter","key": "w","value":157, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, +"metricvalues":{"20":8,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":8,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +}, +{ +"name": "SerializableBase64Converter","key": "z","value":37, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +}, +{ +"name": "DataParser","key": "C","value":117, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +}, +{ +"name": "CharacterConverter","key": "E","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "NumberConverter","key": "v","value":88, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +}, +{ +"name": "VariableParser","key": "B","value":42, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":2,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":2,"3":1,"1":2}, +"metricvalues":{"20":6,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":6,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":2,"3":1,"1":2} +}, +{ +"name": "StringConverter","key": "m","value":51, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, +"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +}, +{ +"name": "DataConverter","key": "Q","value":13, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +}, +{ +"name": "BooleanConverter","key": "R","value":29, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +}, +{ +"name": "NullConverter","key": "K","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +} +] +},{ +"name": "org.ugp.serialx.protocols", "value":223, +"pmetrics":{"4":2,"12":1,"13":1,"14":2,"3":1,"1":1,"0":1,"6":2,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":2,"12":3,"13":0,"14":7,"3":1,"1":1,"0":1,"17":0.428,"6":7,"18":0.143,"8":223,"19":0.429,"2":1,"15":4,"16":80}, +"children":[ +{ +"name": "EnumProtocol","key": "O","value":12, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +}, +{ +"name": "ScopeProtocol","key": "y","value":17, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +}, +{ +"name": "MapProtocol","key": "r","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +}, +{ +"name": "SerializationProtocol","key": "t","value":120, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, +"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +}, +{ +"name": "StringProtocol","key": "A","value":33, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +}, +{ +"name": "ListProtocol","key": "J","value":16, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +} +] +},{ +"name": "org.ugp.serialx.utils", "value":493, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":3,"16":2}, +"pmetricvalues":{"4":2,"12":1,"13":0,"14":4,"3":1,"1":2,"0":2,"17":0.929,"6":4,"18":0.0,"8":493,"19":0.071,"2":1,"15":13,"16":247}, +"children":[ +{ +"name": "LogProvider","key": "H","value":20, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +}, +{ +"name": "Registry","key": "P","value":125, +"metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, +"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +}, +{ +"name": "StrUtils","key": "N","value":151, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":1,"1":3}, +"metricvalues":{"20":0,"21":0,"38":8,"22":0,"23":0.0,"24":149,"25":0,"26":1,"0":3,"27":1,"28":36,"29":1.0,"30":0.0,"31":1,"32":0.469,"39":0,"33":0,"34":27,"40":8,"35":15,"36":0,"16":93,"37":0,"4":2,"8":151,"2":1,"3":1,"1":3} +}, +{ +"name": "MetaprogrammingUtils","key": "M","value":197, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":4,"27":1,"28":2,"29":1,"30":1,"31":1,"32":4,"33":1,"34":2,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":1,"3":4,"1":3}, +"metricvalues":{"20":5,"21":0,"38":9,"22":0,"23":0.0,"24":196,"25":0,"26":1,"0":4,"27":1,"28":85,"29":0.0,"30":0.0,"31":0,"32":0.801,"39":4,"33":5,"34":61,"40":5,"35":18,"36":0,"16":96,"37":0,"4":2,"8":197,"2":1,"3":4,"1":3} +} +] +},{ +"name": "org.ugp.serialx", "value":923, +"pmetrics":{"4":2,"12":1,"13":1,"14":1,"3":1,"1":2,"0":2,"6":1,"8":2,"2":1,"15":1,"16":2}, +"pmetricvalues":{"4":2,"12":3,"13":1,"14":3,"3":1,"1":2,"0":2,"17":0.071,"6":4,"18":0.5,"8":923,"19":0.429,"2":1,"15":4,"16":405}, +"children":[ +{ +"name": "GenericScope","key": "L","value":333, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, +"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +}, +{ +"name": "Scope","key": "s","value":353, +"metrics":{"20":2,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":2,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":2,"3":4,"1":5}, +"metricvalues":{"20":6,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":6,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":2,"3":4,"1":5} +}, +{ +"name": "MultimediaSerializer","key": "k","value":25, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, +"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +}, +{ +"name": "Serializer","key": "I","value":212, +"metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, +"metricvalues":{"20":9,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":9,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +} +] +},{ +"name": "org.ugp.serialx.converters.imports", "value":132, +"pmetrics":{"4":1,"12":1,"13":1,"14":1,"3":1,"1":1,"0":1,"6":1,"8":1,"2":1,"15":1,"16":1}, +"pmetricvalues":{"4":1,"12":0,"13":1,"14":2,"3":1,"1":1,"0":1,"17":0.667,"6":3,"18":0.333,"8":132,"19":0.0,"2":1,"15":1,"16":49}, +"children":[ +{ +"name": "Import","key": "F","value":48, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, +"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +}, +{ +"name": "ImportsProvider","key": "o","value":84, +"metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, +"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +} +] +}] + } +; +return ret; +} +var EQ_METRIC_MAP = {}; +EQ_METRIC_MAP["C3"] =0; +EQ_METRIC_MAP["Complexity"] =1; +EQ_METRIC_MAP["Coupling"] =2; +EQ_METRIC_MAP["Lack of Cohesion"] =3; +EQ_METRIC_MAP["Size"] =4; +EQ_METRIC_MAP["Number of Highly Problematic Classes"] =5; +EQ_METRIC_MAP["Number of Entities"] =6; +EQ_METRIC_MAP["Number of Problematic Classes"] =7; +EQ_METRIC_MAP["Class Lines of Code"] =8; +EQ_METRIC_MAP["Number of External Packages"] =9; +EQ_METRIC_MAP["Number of Packages"] =10; +EQ_METRIC_MAP["Number of External Entities"] =11; +EQ_METRIC_MAP["Efferent Coupling"] =12; +EQ_METRIC_MAP["Number of Interfaces"] =13; +EQ_METRIC_MAP["Number of Classes"] =14; +EQ_METRIC_MAP["Afferent Coupling"] =15; +EQ_METRIC_MAP["Weighted Method Count"] =16; +EQ_METRIC_MAP["Normalized Distance"] =17; +EQ_METRIC_MAP["Abstractness"] =18; +EQ_METRIC_MAP["Instability"] =19; +EQ_METRIC_MAP["Coupling Between Object Classes"] =20; +EQ_METRIC_MAP["Access to Foreign Data"] =21; +EQ_METRIC_MAP["Number of Fields"] =22; +EQ_METRIC_MAP["Specialization Index"] =23; +EQ_METRIC_MAP["Class-Methods Lines of Code"] =24; +EQ_METRIC_MAP["Number of Children"] =25; +EQ_METRIC_MAP["Depth of Inheritance Tree"] =26; +EQ_METRIC_MAP["Number of Methods"] =27; +EQ_METRIC_MAP["Response For a Class"] =28; +EQ_METRIC_MAP["Lack of Tight Class Cohesion"] =29; +EQ_METRIC_MAP["Lack of Cohesion of Methods"] =30; +EQ_METRIC_MAP["Number of Static Fields"] =31; +EQ_METRIC_MAP["Lack of Cohesion Among Methods(1-CAM)"] =32; +EQ_METRIC_MAP["CBO App"] =33; +EQ_METRIC_MAP["Simple Response For a Class"] =34; +EQ_METRIC_MAP["Number of Static Methods"] =35; +EQ_METRIC_MAP["CBO Lib"] =36; +EQ_METRIC_MAP["Number of Overridden Methods"] =37; +EQ_METRIC_MAP["Degree"] =38; +EQ_METRIC_MAP["OutDegree"] =39; +EQ_METRIC_MAP["InDegree"] =40; +var EQ_SELECTED_CLASS_METRIC = "C3"; +var EQ_SELECTED_PACKAGE_METRIC = "C3"; +var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; +var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; +var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; +var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; +var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; +var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; +function EQ_GET_COLOR(d) { +if(d.metrics) +return EQ_COLOR_OF_LEVELS[d.metrics[EQ_CLASS_METRIC_INDEX]]; +if(d.pmetrics) +return EQ_COLOR_OF_LEVELS[d.pmetrics[EQ_PACKAGE_METRIC_INDEX]]; +if(d.prmetrics) +return EQ_COLOR_OF_LEVELS[d.prmetrics[EQ_PROJECT_METRIC_INDEX]]; +return EQ_COLOR_OF_LEVELS[0]; +} diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/table_data.js b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/table_data.js new file mode 100644 index 0000000..29859d4 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/modeldata/table_data.js @@ -0,0 +1 @@ +var EQ_Table1_Title = 'Classes with high coupling, high complexity, low cohesion (#0)';var EQ_Table1 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCCBOLCAM';var EQ_Table2_Title = 'Classes with high coupling, high complexity (#0)';var EQ_Table2 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOWMCRFCNOM';var EQ_Table3_Title = 'Classes with high coupling (#0)';var EQ_Table3 = 'IDClassCouplingComplexityLack of CohesionSizeLOCCBOCBO AppCBO LibRFC';var EQ_Table4_Title = 'Classes with high complexity (#3)';var EQ_Table4 = 'IDClassCouplingComplexityLack of CohesionSizeLOCWMCRFCNOMNOFDIT1Scope ▄ ▄ ▄ ▄35317517349022GenericScope ▄ ▄ ▄ ▄33313814460313Serializer ▄ ▄ ▄ ▄212792153433';var EQ_Table5_Title = 'List of all classes (#30)';var EQ_Table5 = 'IDClassCouplingComplexityLack of CohesionSizeLOCComplexityCouplingLack of CohesionSize1Scope ▄ ▄ ▄ ▄353very-highlow-mediumhighhigh2Serializer ▄ ▄ ▄ ▄212very-highlow-mediumvery-highmedium-high3ProtocolConverter ▄ ▄ ▄ ▄157medium-highlow-mediummedium-highlow-medium4VariableParser ▄ ▄ ▄ ▄42low-mediumlow-mediumlowlow5GenericScope ▄ ▄ ▄ ▄333very-highlowvery-highvery-high6MetaprogrammingUtils ▄ ▄ ▄ ▄197medium-highlowhighlow-medium7StrUtils ▄ ▄ ▄ ▄151medium-highlowlowlow-medium8Registry ▄ ▄ ▄ ▄125medium-highlowlow-mediumlow-medium9NumberConverter ▄ ▄ ▄ ▄88low-mediumlowlow-mediumlow-medium10StringConverter ▄ ▄ ▄ ▄51low-mediumlowlow-mediumlow-medium11StringProtocol ▄ ▄ ▄ ▄33low-mediumlowlowlow12MapProtocol ▄ ▄ ▄ ▄25low-mediumlowlowlow13ScopeProtocol ▄ ▄ ▄ ▄17low-mediumlowlowlow14ListProtocol ▄ ▄ ▄ ▄16low-mediumlowlowlow15EnumProtocol ▄ ▄ ▄ ▄12low-mediumlowlowlow16SerializationProt... ▄ ▄ ▄ ▄120lowlowmedium-highlow-medium17DataParser ▄ ▄ ▄ ▄117lowlowlowlow-medium18ParserRegistry ▄ ▄ ▄ ▄110lowlowlowlow19ImportsProvider ▄ ▄ ▄ ▄84lowlowlowlow-medium20ProtocolRegistry ▄ ▄ ▄ ▄57lowlowlowlow21Imports ▄ ▄ ▄ ▄51lowlowlowlow22Import ▄ ▄ ▄ ▄48lowlowlow-mediumlow23SerializableBase6... ▄ ▄ ▄ ▄37lowlowlowlow24BooleanConverter ▄ ▄ ▄ ▄29lowlowlowlow25MultimediaSerializer ▄ ▄ ▄ ▄25lowlowmedium-highlow26CharacterConverter ▄ ▄ ▄ ▄20lowlowlowlow27LogProvider ▄ ▄ ▄ ▄20lowlowlowlow28NullConverter ▄ ▄ ▄ ▄17lowlowlowlow29DataConverter ▄ ▄ ▄ ▄13lowlowlowlow30IsSelectorScope ▄ ▄ ▄ ▄1lowlowlowlow'; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/report.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/report.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/report.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/reportforprint.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/reportforprint.html new file mode 100644 index 0000000..9d4c074 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/reportforprint.html @@ -0,0 +1,28 @@ + + + + + +

    Distribution of Quality Attributes

    + +
    + +

    Metric Values in Sunburst Chart

    + +
    + +

    Metric Values by Packages

    + +
    + +

    Metric Values in Treemap Chart

    + +
    + +

    Package Dependencies

    + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/sunburst.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/sunburst.html new file mode 100644 index 0000000..84b00dc --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/sunburst.html @@ -0,0 +1,106 @@ + + + + + + EQ Zoomable Sunburst with LOC and size metrics + + + + + + + + + + +
    +
    +

    +

    +

    +
    +
    +
    +
    + + + + + + + + + + + + + + +
    +
    + + + +
    +
    + + + +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    + + + + + + + + + + + + + + diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/treemap.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/treemap.html new file mode 100644 index 0000000..b5d817d --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/htmlx/treemap.html @@ -0,0 +1,56 @@ + + + + + a + + + + + + + + + + + + + + + +
    + + +
    + +
    + + + + + + + + + + + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/main_report/index.html b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/index.html new file mode 100644 index 0000000..2da414b --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/main_report/index.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/html/workingsets.js b/SerialX-core/codemr/serialx-core-utils-split/html/workingsets.js new file mode 100644 index 0000000..d87de2e --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/html/workingsets.js @@ -0,0 +1,3 @@ +var EQ_workingSetList = [ +{name: 'serialx-core', path:'serialx-core'} +]; diff --git a/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.mdl b/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.mdl new file mode 100644 index 0000000000000000000000000000000000000000..6305f6b3e223b0f48922365e740d758221e23284 GIT binary patch literal 48071 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 z zm(^yX`1F&Xc>|!f;<0q(?ifN20_dyYoFwD{u{Gn^dR`T)z^S+8FrgCa*~aF=Ev2Jq zg6>cK`R!SMcGP=w*!#$%Y?-|PbGUk*Z%2U_HO+DL8=CM4=D$@P1(SXyL8wlB=k1kj zY70X%chDUa>G?STC73-+iR*565%Y0cClNMj3ZJg3<`O5Vz0g7Z;rc4!jMw zNfIWb5wV|WbVkDuW&A}+YE9z5d5dQ;8d91)01gj2h3j^RJl>N$8Q4(8Act=0=z_K( zCWbepBD%P;4jlMjtiw?#Qp|6=%vd>4gv~2&EdTL$zRa5uT$)7_={#~h& zQ4X`ph3EMdsAA!{ho^oTLYMp+5s`hJdA4#yxPhH5-)U!RXk`h#^8qmwsxQ&>vB$JP z4byY6QH~*W$=}9S)d}pO$VYPhAS+tT)RAfwbr_bTVZEP2=!U1)XYosOF!~ zVLMNL^(_612*5*E34jgHHL?Ho?uAJn>#1WU|wKtMq;^uoM8p)t(B!zOl@+VJ_Z@3X$E3rUzLoZ9C`Av;jZswq; z26J7*U)$1zRY+R2YLjn{=xGWA65Ho-(W=7Rq=s~NHSwH|rdbf^QT$Dchs24;_FRG2 zG?+ln?q6CxC`oOv@=IAfGRfq)^6;_90CHkuW09Ed3w~Zj-iw6Hwmnq}jaBZ5i85ZM zKcp*C%|%xh1(4UdI;bTr8uF+T6bi^H5?6CA2OEeCAenQ8_-@_440%AsBD={lO@7>w zslK~zp#{9b$RDHN3rU_u@fB&*09ULS$oGG@(Cpo}vE{-6q<+SS&k=n0IoPUi@V&b` z`D6;Fg=WeQAkTB9;JGMYdw%r^aZ}t)r6cLsE?QecdgrR4^E{R!j<+V1=3UrAyFp(^ z?`KHzTp@72N_4ImGH+sWlI0NpkiOR~1I^zPK+fFgmYM#{m8T9=b-z&uyfZ~z;Y?_;A7!4d#Qr_?ROt1_W(*``$lLtnSBaohkB ziC0P3K+)+kmmD^6@;rA7Y~jXdy9PGY7(g2FN|_t==yln<8JDxMcPHPw>$n~oOh_`$ zX4oymQ;1(z{he)Ux{fv!A>nul4{RxzHQ9C9i&PN?Sk3g&s6qnrCQudO)-AJxkjN6% zDji+jaMAl8vXxiJDiUKaY`_S=pR_>85_-zfT-dWUotfYd5ne_^*S4Cz$-M8>o{3{B;Rr0aw^6E9R zXlE^O>FOGK(Lx@5$gNj~CYM={8_TJrN89jbI3~J5bO5RH(aCIlg1wqvjJ^9)`FBX$ zMn`BM13qNXE7y#o1bT%vs3L)$VR#;T)j>l1%1MDu@aM7DryA*irlomkHydQfr}O8P zZe|hoJg6YmWY04VeAen40A`i^H9?{`=5j>l0NzLPi=`~QISKm%2xBOe{Z~kBIm;i~ zXGl!v?f5c%+sHUKep53Gu#C*bS}Q6`S{7J3@AL8;un874E6g?T{UII&w^0m>zM>S^P&QG54E zZy^EYa}UOVO$kU?qew;oWkbXxqaM(ck}WYA`T@^_DCJ6=8xF(ACqZaag40J-;1O{@@{)q&}GWSFdKLLFlkVZMzB%%BMOupr< zp`%|D7@vvtMD*pd%3fYSk-t_4i=+Gpzj;MIx6xmWD5MGZ3^4`#K-sh=w)!-UyhMp&Go6jd5m)W z<4>?(#SgG+(gp68m@l{Tqr4%?|uj-iSeANinl&)>w zHv!J4l)#yJs9j9u2hKbL-5(@^6;M?&3KJwb35CpK3L9yZUmM{X=$J)RD_tYOi=Fc# z^M-WaLI%I-IcOYV<_5kZC*8nh1v$(`r%pkRZkt(F)s~zrA`Hc4?8NTIQDjPUz8qi0 zVD<-#N-V`g$l?IM2esOmuV*`H=F3^K4u9QirdpVIDXUZq58-{8H+X8FQSc0t5f2@m1585RX2!744f&O^30e4!vClJDARHc6<_sg=>_L@IbNZa6lm#nA!uj?OGG*Wt>x+Hqy0UA7M(vp1GXfcphR;j0h_5? z=*BPS05yD@W(sOmGojf~s?qY=^3gS4Lm0wt0!opD=%Vd@kvH2flz`T;(X~s%OA54? zi)b{x5ydurdTlZ#*rva#xJ<8Zl>k$BEGOf|`wicsc?h!us`tgEK#XaSo4~pfjMnVb z^|C#ee^Vnho)RmdCdwPmrnwQJ29(B^I=v5um71U4LoaUbTliaw@zUL;(!(`eXGDhw z@hzU}K24xw-QtmP$Dl!q2YMt#w;Ug9Ha)=3Z#AK-n1EG)R4f7Oj`SY5e<2-M+eXv9 zM35J-Ca@U%1hBg&Zr}R`(*aqF(s!{|X#|_{Y2ofL_-ebam7a_M2cc33Cw@q7znsdAbh1<12J8mGIv30j)_X%wDQ$Pzvjs=b$wx z>^#vJv?9F1Wv99-@ERK0F*=0ZD8l99{q>7*IUUZ==7o@+!38+~^af&HOs^DIMZ$W9 zsXJ&>9Xd^;7=qyBHW=K$4x{7Zotuwr@p)EQq!dau?mUKp?_)89eJrYGlOai)J7BOo zrhzW2fxRnI1TM%rs_IG1JW5y!v2GtF7oV=4_l;m?eoJu{JNH zyQq{I!X{5N^-ZmvZpdUZE0Fb+=YznU^yKOMq}m2;-%wt~j&-eKR@?Gz*=ZrLkpCuF zRG^SZhn9HV2#3Uzc#O2Ip8!a`{Y*|!dp;#SN*b1~gURtKxoUxa9d8s(V0Bmw%g6qB ziRMMfz?nR^&kWA90sXNmpxYnUe{Ft{An6@RgS`7|{i8L^eH-1&Duj`jZ! zpCKhBa98urF#|Rb(9=S-P4KPJtk8e9`}p_sZ~iy_wo!ll*Y|@k3ijf^CE`tq0Nc4g zPiN#TmT^}XA0V`Kv1^%V(My3MkLwNcz|_1;VhWOx@<~iA)(8Ekbh?Fhh6=7`-j8-rhgcP z&raXJ`fCu(lHbx)dIBf)Bz<^`Q|BZ3ojFY3LWgA@E~rRfF5=ftaLeRi`@kAvg5-3z zT%^Bk1YZjYFEK{rAF?sF4AUqn5RjxgS$xm&R2-z+8oHa@_3czjQXp9bKP?us{Dvx3 zNn=Pe1ipc1jxk=lGleyWF^(Aii{N1y%opj$xhe~e=b-o<`_L8tWVzLhw0^f^5NyVVMOHr5~0*h2v$+t~(nlgS%1*-31t1xS-M2kM4h>>!}31Oa~wl4b_IBYil~XZ3(Q* zuBxGAYo|QwBHC$0y#H+gpI1@kz<;CxpSd0g;GTK9{*{A?I{wNb9dE{L7R(@3*!EG(^4q*+XGg#cw$Ka`q4MJUrQ#o?kKhbg_^a)n z`Y@d@XR|PhmvQpl@n6d~Suz9VhA%QjXz%t$KDl+Si-j7yZM$0GDY$7}Kq%IvZMByH zW~)K!&F!O@t+si~?zS4_!5jwIt+p2bAbn&PTkU0YTa6?V-^%a4VaIlyYWr=wWMOaF z4W+8g{dUT^-#`wR_!*4H_H>sw8OSWL2w^~iF7`q4(SjTQFysC@>yNL)Xc7#GzAQKT zE}4FOWP8&#e9W$gCYgKqfLIO;Sb1K>_(PXp;(7n83Z{a7ttMe*@R~cG-+tMDxwbi_ zIaG8@vt+pL|3O4HMQ*Whc2yba{x~1+u`eDBTK-mr~W_ z#}+IQs3jX2(0ZpAT@;($j<_x-U}tvuP-K_i4y4ng=%$ACP|Tq2{4*LYf)v5>Bb5Pk z=6PB{l{ntN?iy}ptj0l?RL-F87>vVtc{uEf9gBDr9#GW}sDsz+ zjn794LtDYeS9&N|V2!a|j==d}e38t9VE2=o2L@);8EZvK_@kxF>Wk&|br1!^i=fZ- zFhtOipMRXEMv5=n)hQoAg40?9$(-)1-_V0Q34q%Z#T7YG?p@gjxaoV?&`tz%nBvzB z-;So-Bc%x8`Z*erDgKDbBP`;1X%b&1&o;g#cLbdcs1v&gZ}rof4do72Dl_e0_uFqv zSEA5?8i9A<4WT8eGnS*%zbt};aT$M+o577t{TA-BqrZA**EzU*8XOjjA}#?_6+4&V ziqS1>>Bj66#c{X+B#)eFVxh}?#r~7eFRHFLt?W4S%nSII5%t@H(FEoIR8A*Pdb5@XFybBkv2{{Dk+|FkZ{UT&!+R_z} z>ngQzauWu3%l6Qg5_ek9cuYyg;{o2Z&_dIrBeW&|OB3ObB!NqM3`93H zOPze8)xxJNdDnKm`+_!0kg;^*p^|1^-~%*Quyns9 zfI+(ts}YfzLvGh3V~cB@!z8cdRKc6#SHt>eO&c}Hy6&p9Rd|5}&y~vq7|-l^G@7C| z$pdUok$IN4#B#6MnZp#eikK0(#^uC21@RA7&rmZUX`3TKu5PX)p#{B_AM`goU&p3T zJU|ZGhTtr9NEhG~^GLS>rDZ5(+UB<_G$X7{{ZFG&%YP7w`3WQ1JQaeGI>HHIaobSOGc+{rv%hmY3BjyUVr^gzQu29 zSf2DLwbdi>m(geyi>aTb*lxchhj0{JlV+~Z(mz#1dU}UOS~kd@hi>&Tg%yx7KEDwE zR&A6s-_kzJEv#i-w>%Sxa|l@~n^JqUQ@5CwarE^0Hg5oDpfG1+MJ#eGcw~Rq!ntjD zzG~+-b++M|y(#=}wvLi>WBdL0VQ}4Fju)F_v;5u$tJJ|aurF`LkA9=GE^%RW^K5xD zd$tny*^faygwfz~5JQ=0n4^zB^gi~-y~F4GpL=hDFTJEA!w;k@LzxY72m9}QWC&bK z2C6;MYvaE6EIY%`=F#BUB>uv5p_Gm2fP7-JqDl9m;*$PITeh06Z4#6>%eI~jiJe*e zSc>}p{J)GlDBJq+@ITr=Pc6sP9nKYB2lJ1e{t6PbJo`)~v{#B`>H7YU9*;)XY@LHA z9aOwj48ylIPR;@(7#Gr26~s{r(BW5J%WB5rhaF9 z{q9tEWA+GEdpn*7m3K3Kg5rWBIM0dQ-=9U{O>9q2Vq^6K`Q=8XZf#bwBEN+JMBVXh zvwZ&J(Ti@G1|?K#7Zt}jTlEW=Z}UEh`M+)>K)9mQUlT5yqxV0+Q9j@Ay+3^NnVBh` z{Azoz_#ysu>7?DjemU>4v$mVjbi=&kV8gfg-cxnPCQC%j;6q78)gjdmwb*cQ9N*^T zZ5+0A#BQWfS~sljHlyhxT#0|wqi&gk5loy66gN*2(F|e(Io^JWPvj8xf+bO0)=uk{ zPu?}84(L_0K2;iNH*^Z}uGph!4$IMMst(>IvGSJGbx-5m7$cbeC{07G#8F#Ctj|+I zEk2nozMPE1X+Snl$tUA8ws%-M{-dYFPZ@uTyX!}=MKylcw;{aD=_}1RI|0DN`!3c@ z#F}S0n0JBD!B(t&@KlV#A3?Mr7m%0zML+%AH|c*af}2>AMqe1AX1p)Y0(!r!ZJNn48e6N?& zBv|oy`JS0}zCDYq<$yswylU|CgIn_q}7}xkEWsTdeSta&>9BOD}}qSue&3q*zB>^-dZL5FF&g+ezDWj3Z_zDnKDYdR}=5+N+kcrtRv z65bg59Gg>3S(kT^k5kaPY;Qc>ShV#mNkT=|%5}d&I)2{)^ltMmtIpyoT$rP{iC|~_ZldNeP$ZbAQu_!|HbizoqJUk;;CTsx`U;BqVx@80dMsk8v#yQYaK3ppC2JuG z$l08G=j5jbJT6s)Q5s)?m?y2^K{qsybKMs&$!JtYrDvmZs;H^y-10FMu zi2qVLOFo#SW9%&LZb03*J<{;u-y)A`@ieREC6X-)FGJ?ta&i?!0&36HZHr@EKn^wm z&0JGJrBufDI8Rv4=Z6RJ_WAPu`XUyam8n+KKYEvU5{WKlIav}LY7B*&7%4v zZO^gWs%E9z)*1WHa$SSt;|ay{)v&KuYHu+ruomH}&-^vtozJ4UNgVvW-eJ+jU!|7J z6c1OlKay^ozcp&b3|lj6rb6SBP)~0AQGc)yI>dC_;e|V4dme#Pw!Vx?D+5U>4Tf*> z94s$XOT$QI?#OJtnl2~6AChXU_%F$LOpC|a0BfA8PXSgCrErBNUVokzA26*udRZ~| zc$>f$t`!W=I#PX2CaCNBn{G3$nV|f%7tMD#KDw#67OX6XQaiAoqgTgxoyFrMV!|km zFW#eQm|QZqiFhJeWjT~awPsqJ$&2;PV5Odb2`em`(%9z{cnF_}SbjLK_FkIS zC?qo^bh0NTrGb{edXg;SlXwxIlmj}39{m%+tc(g0bz@uQ$H(7TCzOrl#{X*|=QS?` z&pj2x7DkKtv(x0ita@a_;sxR#8Yz&jB8}2JFyo6!oUwH80oAWYoN<@I!!no-fcZ3=$K~AJ!jG!?T~|UY zJzw;Uk8#)^zK+7l(IxS?<&W#E5}@XJTr%@KI91{rm_T%qc-zD1hJhlMu0kvSb{)4~ z@T_9GN`*WzL{2{J)7-pQN5u?$ZfQ`KxdWQy=}q?|Gi=Nw8i6cijdaEklXO=ciqSPd zAs$XjH?nTfIif8A%u8shEy1payQ^b0{8t0Vs+yPzoXyF?s&zKsoOJeV zmeQ0$w@teqUyyiL3VF*?nqq@ig93_8RlTPA(zh(LUTsQy4Ow7KZ|)PTOOoMwJg(PB zJgG*i%u1VJ)q^;u%L^&pwir@Mq)`gtOs3>jtnB)O#Ys3Gr-=_qeR?T)Lzr~;iiIBk zO^-Cs@)bqp8IBJR`<-T4lA3zc^Ep~;dftL(b0vpT`vk${P@dLsjNd7kckSvLG>5K( z>enF3fCTO!38b~|Ami8Z=f)(jd~9^~Hc~Yygr<%xtqC49L{138eMHR(sQNu5{AO^q zSqL{}gMP4v2con(tjr>6+Ps8^2k}1Fg3>%9gh|%7Yim4u4e{33qT(opF|7!J8)clp z6A;m#x$uHVYU)zsP@ZFYE!n!#q7%B!31fwjKy&9Il|*QzHXM5#B=Z@U8JKLR?bY#! z`r8D7=ZBugu>c;#`9oTfU8&jI3JV%h#aiuxbJoC~mlu4s$#~HtRi76$^+_Xt-MOd0 zwk)2f0G8`Y@D!wSD78xjm`)s*Q-K-6oSu3~67coizz|_(`W%Pvq=AYZq!>zJN>Qrk zQ7{}0VmbKL_tPtY8lw81^`=Lvzv-k-ep~vxay-J*IAtFXknBrZa3m2%sU5Q;pU=_r zLsPSPDO|8qwqmZU%`mz?r(%^DhR&ld>?wC+Oodi@zSh!Xs_)Ztm}6Q!)W|;-kwqzV zsn^egMVPSWl#%72s3HSswIXZ=QAxfgo5IkY)=7GBL~WL-yBxBt>Fb6rGgx61-EwIs z37)rkEa+|i>io=(>$kQiwu*m4naL;2T=(K4(_4qCGSQa;}!=oa!=d# z>h+l~3Q&ccP9$|I&V5ut0;RMpeH;n14`aE~3v5}wZc60^F0+!J+PY@( zhz%a37-;KPE3GI%;p@kKbeyYxC3UX+Qe;>yBwmWl7NHxPrG71|YdbK7Ktd^N6;_8) z`0OI+591FsOG@E@l_Q0eqK^38Sa!{kQTVz6+cL-`qo7#nJ8mv8g5JtnmyZAIFwoFV z#PYQ^Zz3345+0e@bk;%yb|r_>#s<$Rf3Td+*RvCE5Jur){Q}3I!4~^ADNLlE4DXqH zj#sk@U0F@lY<3W-ZfGYt^`4q;*E8qv^`7($TwZ5j7+l452F||Vk-A=~9m+k&Y`2_^ zT#Js!f8gBNcadqBc%dA&V8wbI<9lq=&WFx=W)85PDYLa9L}s2-)pr>}-cgVtTe zGYpu7R#ym~L9=#y@y?^C4!3GA`B&}pv7$gq9fvUMEwd&OT}t2KFAs=UJyItk^(tU_ zE&C9gj78QDE!0U2gWkzqc7B(RMK{d7I@e-HH=6Z(Zk6aD)@+&#iJM5W66CAA@LDZ_0MCV`hNOuXfddZ=<{C2|! z#GT_CSOASaSy321bhlpSk~r&g6|KeZJTG2~U0DvLv?u-UdKN7D@yy&r z{mCRY6F-n&=I?*B+fEY9G+mE#Kb_wRW8IK+O3wg|*SkEe(}ynF_#q)L?fQM)P-zvN zu_-8&qipT&vD(i|-(tVYp*U%1 zDJqwo#Dm_O!z4i^-dva2TE4UXZ1Xp2MhicmffSK&Q!Vcx%P%w4@-bu74J}pe(4?h` znvP-D>pzb?GV_aL8vH4?Hr9?$+=RmhK-7iA-4*x4rgnvb1OIB4x)qy;tv28+KlwDB>s-k>YFeB3icVK>v{< z%!-Do@p#8>nuxSlkw&TAR`FhVJilCC&6Bf)b3Z(3_O5#%?W!wvNZmMNo4fQnhEp$I zDs<^h?i{Pbtu$=DF`}Ms7*le-#&eQ#6~sF_e(f-2St>r51lL9L1L_oSD>u?^tnE4s zF|Og)yCcahqrg>BoQbcwhQ#Z}LTRFiLO1J0(ki6|Q$r{RC*yD$u&Jd`Yv#U&o@zq2 zZY&t~NX3?qr#F(b$`+{JrIkWEhT)h9c*k^6aUK!I9iL+cgs>;Gm^Xs{YNfHO?`QN3Ua<;1(Ax8YCekTA1KF&IG{!d%hUn^Z zYEA?q#x#QYZ9+um%}U&j$WxUp4SLR&Z`R{4!X;;9rYVMR@nsYLEBPdiPN#>=;TC7r zhhBc6#kl)XejN+g*C@@L8(+U=cNk>*8Ca6q$j$QW>pY_yu2nBOUY(#4PoL!JJQB)A zvP>%qq_ovh67QjUa7z^<{}#c&$~`~SZQbBZBRnS>h;Qw7yh^WHFCo8{9ETyGP zR3-JKy*zxLZLI{(QBG&5y9rnY=+;m>8_;7sC}=&RY|Uz=McH;gljT_jOWXL@(Q)Gb$EL1a zyBghNJgKQ&Dhyj|rRM-UMNbj)MP7HaT;pv=MZ1{H*7EwzBQF>l0hfibMfSXAAb9>R;l{iXcoLMSK#0Ymm zN`HCVk1m6UWiTBCvG(P)L77=i?2873RC+!tFEYb+c^WB#IbYJ&{7RfoVGN2JxCTdJ z#bT08q4%u5aU>$7((}3uh}xN0Ty6dMU`c6 z2wXz(>>mD$mDUlNd;(Mrk70B3`e3Idfi#E;!aOc~9bWwKLA)2Cm@rD?t2}RH$_mNL z@%XhVhoi~}bmL^K@02ucTWf{Gqu^^^wf*5IF|IRB6V9Hh_Ee+Yj_zUBvLLgJs-u65 zi=LVf>Khj9`6Xe|*C2;sM4?NvrC#o?)iG!Dhi9CjyZ;FPQ)U575elm6_@9|_Ym`p$Q@CaVQEx%ePEqaQnG z@di5MTxTIk_L-Pf-|m=pWw1}>V=VfM)1 zn-H>&$#^e&_Q(GhSH|v3KhAZ-(4F1av7gcI_Kt7)?bWd>d#x=!^9Qr!vvN+k%xrNllA+$F^v`5mZYG-wsxBdZM3c3_6Rz@ig!+bu)y`9 z9>VFw^q~gt_=<9~P2GWeayLzOw=EA!BI&i2@Xx*XhfgSmnrLzXWUy^6xjbFcJ6f;Rm)BK85V_b1UO2b z<15V9(iEmj5Ol)|l(I*3+w<$Ox71D5N-`BnVko7#2o$#dr}@Ci>bIHe+*Qz@&Yzu5 z7g0E$r7@YU@)o`6)@Y2)2x z*GpZ%7y8rfSxPn@?~x=%;pirZd_24mj-bdDx;udtOsb@5>pYrfLwF(trBNE;im9lE z$Ln?bAYP0kB#YAM%G$by=JT4Oh-ZJx6^5B03MYIK;y$T9mkey0#qQv zF-@K0^PY$|f~+iu(ki4n%aChpJfbhyb489Hdn=C87-P$npn__?+6pS$#;dIw8pfki znbh(tOOt$S>Im-xj|U$TH4F0KtBgQ5mV15Te8PNTwpblQ=KNjoXWc3hHFJw@ zc)GD|>iE_?->O5NG<^Vbq*HnZ%FMW@wytTs9(7YG7UcTXN@FKbrRZ`z9S?SEo{p6? zN+Fza3XqF`VxJu>xLyF9cVYnB#$mh@VuE}{eh1yrHCRk8$MKM15Kn`yC+lBSxQc4r zbhag$&X$!pN@Fao`r5F0 z&DWZ!=aV6HSLUm7jSS!E{LsGBS?_|=Idhl8V9Ss9T=a1rCXc}#7sPOy$R8j z#=h9^sTn)?eu1}xo0F&;nQisELYaoPi&kip{_Kd$0&%^ZCh^s0uUG##O2gS{>Mk{* zm*2<_?q5Ns3#mhRjLVP4NMV@1)&BBB=v!QqX~Xplj;A#e=i8Agv(hI?EtU?`v^g9| zQ*nc~0m+m`KCk0$f<>(3QkC_5KV3hhg9%^FE}K%br6PPSYBJujtyFC&U$9gDwF&PN zs+}+7`g=U>d@Eq|wd^0$F`QP+jP2!`%m>IuFSMLYLr1(T=L4+3tA5w7CXUia6rW3o zRXDYS8Znp(+#qLCyW{MJvZ!+x*6o_D!^DcczIinzJp07KX1T7x$terP{o>fyE4}@z zlN8vF!%?x3I2DqpI7(xTEN$~RA)Kk-`y5y0K8VD2aJ19NntPUse!+m%+NW<#{QhPi>z|`Fzzx7EMKg zl(K%y_RJ!R*Zp-EO+@kw-~)*U|HRSsa3kVus}XD^kG8E;9`obVAvEjDcFmgXRu~<^ zi9)a`dbXj7BX+>z`Jr!e;{6YwWJOS#kzHxc)B?YfX>-zDCry;}$`xO!In4V#_&$~3 zUeu@Z)%j9vV@JM}?seAUT!8N(ccI_~xRcOy!@{V4ohD7k>NRf_^6<2@CK~I&7c}Lg zRB+&rajDb$>*-GW&P<^$Ezgsf5XWp5=SFQ#K&9*|TtY>fN}*X6$Euyy=!naGaW`-i ziDg=v&Y>lkiucrRKr*F~7hvh~9Uk8$jL2f)78OTnjFJ9t%I&h`o623~1vfaxfzA&B zz!LYSLjWp3&<*3HZnQx6G{2q|PIdKVke@CmhX;T3$IGDDn}+-;Z90>i@k}!s`owZq z==?Q)h02%okvc)B+^wDtBcyViASEZn!Rd6q=ua1;_}lpkrlj}LyYO;3xIIhIrbigp z>D8yxKf*zh+1BevH^HKUI=zRH60|z)6bRi=sBB0D6|8P+dMyRZlc?(UK$5=cJbIz| zNV<8)k*+h=-hBP<WEtsrh5u>f0k;t6bEl8=~eAxfSi z^OgG%|2dwd&9q-%XCEBL$J0338mljgf_N>hUNM?yw9MWQ*ZuK4fa=_GHl;w?KmY8; zjz6XyGp4CqZHDY=QPX1OP^_uBWlIzBwxnXhD1B(0Eys(|Bp8nR*{wSc`@`31H)Ud? z?Qb^O>(Mx0)wkKCm&{Gd>Ff9bOb5EHV>`lk!;GY1A=aAF@$GsWn=MM6j?ToRY#J_) z=)MLWVpTbm-q`JDX7h?4U?Okp#SfJR(~W)KK;?sDd##Xq2>93?gF{mu!QQ75UH*wU z-P!i2?gXY|^TI0Py*)+6Q5xf{u`%e+7rn4Cu9fd&4fOqrZ3TMEE?1qRStSP?OKTL0 zn_4Q5xf_bQu32W;F3k6nc;8xoJXb#b&H5h~!Odt+t~m!k2Agc;*I{(@9_RV}w)dWz zyTf_^QS#Ui@z2tge)9sX^!L>-d8#AOjdjl%4}UYfr`ar)r`NMtP+~Pzi9{i**EQGW z6(@-ktTZZPXAa}|VvrCS4;k^NQ|jd(5#Jp_eIk^BP)opWZ1>vv0hXmp$PcJ%m|`hS z`8|1Is(>tGx{}OFZ}Mu6R~_R8e$|o}Snq-txE>?C?(_JUX5#Icnh;HC?CTNvdOnBt zc`9D9)_`Q)K%TX6E!W}MXrZ`o1p9iWF+?zQp;GR7-$N`QQ}a2A>|qnJy|xCT^t|T$ zJ>zg19P!*ZPzTUzRAsoeU<(>Cx7O~5`S?tHswc}ZYqFbGw(#rGI^KW|bhnKFS;p3lF$<%`{Ml*pUsga$*E}BML?Z+@Rish-SSu-4 zb1j2s>GNG1|=14(|q4x&=?vW>i< z4%B5{m$&`sGI&@9(?M|Pxtz0qrZ;gLt}mm~ zv+-!U=x}bycd#}ZeM^2!7(K>I3+<9kIt}fhRo5a+=elB}7(%P^a7Kh#?ge;P~c4MYOt21B!Y$*~&+4mQK8D%SjNW)WD@{W3U8ruAk0JXA`ObaKmA}k~*^qCf&KZc(JfCQs*1C%O2sW zEUq0ms|Q;wp3_47?uKpKYxt%^nU@dKe)Q%2EX_*AtOuCFnfr=Li-Pv@uX<$^0HH6B zZ4*yZ{`%Nfu=Eal7rfOm`UR|x*Hm4`Ss3uGO)rbR2SO1Lg?qX6QN|)1{Rzg_pUuW! z@&n6}2$zg3;rAVXA#Jgr#3S5{FUzG%z}#}_MqhGdx)Hh8BFJ>_$vBfAcdm3EUER}d zERU|t-S*wy1#-u2SK4eX>=}aWNc7N1qJ{B000310RTz>003vZ00000ye-cu literal 0 HcmV?d00001 diff --git a/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.qa b/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.qa new file mode 100644 index 0000000..fb2a649 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.qa @@ -0,0 +1 @@ +{"metrics":{"Number of Highly Problematic Classes":0,"Number of Entities":30,"Number of Problematic Classes":4,"Class Lines of Code":2324,"Number of External Packages":9,"Number of Packages":5,"Number of External Entities":370},"distributions":{"Coupling":{"distribution":[0,28,4,0,0,0],"locDistribution":[0,1796,747,0,0,0]},"Lack of Cohesion":{"distribution":[0,21,4,3,2,2],"locDistribution":[0,852,312,302,549,528]},"Complexity":{"distribution":[0,17,8,4,0,3],"locDistribution":[0,749,284,629,0,881]}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.ws b/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.ws new file mode 100644 index 0000000..fba9370 --- /dev/null +++ b/SerialX-core/codemr/serialx-core-utils-split/serialx-core-utils-split.ws @@ -0,0 +1 @@ +{"serialx-core":{"name":"serialx-core","packages":{"org.ugp.serialx.converters":{"packageName":"org.ugp.serialx.converters","isAll":false,"classes":["Lorg/ugp/serialx/converters/ProtocolConverter;","Lorg/ugp/serialx/converters/SerializableBase64Converter;","Lorg/ugp/serialx/converters/DataParser;","Lorg/ugp/serialx/converters/DataParser$ParserRegistry;","Lorg/ugp/serialx/converters/CharacterConverter;","Lorg/ugp/serialx/converters/NumberConverter;","Lorg/ugp/serialx/converters/VariableParser;","Lorg/ugp/serialx/converters/ProtocolConverter$IsSelectorScope;","Lorg/ugp/serialx/converters/StringConverter;","Lorg/ugp/serialx/converters/DataConverter;","Lorg/ugp/serialx/converters/BooleanConverter;","Lorg/ugp/serialx/converters/NullConverter;"]},"org.ugp.serialx.protocols":{"packageName":"org.ugp.serialx.protocols","isAll":false,"classes":["Lorg/ugp/serialx/protocols/EnumProtocol;","Lorg/ugp/serialx/protocols/SerializationProtocol$ProtocolRegistry;","Lorg/ugp/serialx/protocols/ScopeProtocol;","Lorg/ugp/serialx/protocols/MapProtocol;","Lorg/ugp/serialx/protocols/SerializationProtocol;","Lorg/ugp/serialx/protocols/StringProtocol;","Lorg/ugp/serialx/protocols/ListProtocol;"]},"org.ugp.serialx.utils":{"packageName":"org.ugp.serialx.utils","isAll":false,"classes":["Lorg/ugp/serialx/utils/LogProvider;","Lorg/ugp/serialx/utils/Registry;","Lorg/ugp/serialx/utils/StrUtils;","Lorg/ugp/serialx/utils/MetaprogrammingUtils;"]},"org.ugp.serialx":{"packageName":"org.ugp.serialx","isAll":false,"classes":["Lorg/ugp/serialx/GenericScope;","Lorg/ugp/serialx/Scope;","Lorg/ugp/serialx/MultimediaSerializer;","Lorg/ugp/serialx/Serializer;"]},"org.ugp.serialx.converters.imports":{"packageName":"org.ugp.serialx.converters.imports","isAll":false,"classes":["Lorg/ugp/serialx/converters/imports/Import;","Lorg/ugp/serialx/converters/imports/ImportsProvider;","Lorg/ugp/serialx/converters/imports/ImportsProvider$Imports;"]}}}} \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html index 9585e30..c063376 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bymodularity.png index 9054b7d5c896edb0ba9a9fdc9494cb2e77b2ccdd..819f4e64cdade4aa091aadb84a4f1461ced0fa4c 100644 GIT binary patch literal 27509 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 z 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 Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_bypackage.png index d28d53fd6fee009c4c2914d25fc64f08fc357cb9..6bcfc3fc47660d315d87dc8f654d7434eddca9a4 100644 GIT binary patch literal 34216 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

    53lqn6Th_UD4~wiHDNc_7F6 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

    a5GdHwpJ9;ya zJPCNT3AtC}$4&0@GO^8*mCR^6wE%I(G+8Mjeu3$`*<83)K zpae#v)Kw3JLm{33SVbtSkf>M`Oc~*>AFCM9a$GaV>+vw-a4l+D`?einXS4i1AMN-s z;a`k3^U0Hd6HyPR1=d%B4q4AG5{{NuJx2(PmE8i!O9$VqAQ`eI;wjN7PfQz(gL>^e zXJ)c=US6_`btQrVcE3y{ns|EUnAMpRciPnKDClh#t{P+3%w~EMTF{?ymXap{_d81Z z?Zsp(i?qL4Q`Z3xcvqr7#KpAC5>_f?sOe1+Te#23Vw+D5iFHu>4znSpP*p8E(y1m_ ztN1$v!-jRL(#BNL4;^=aIfIo++IC{5kuL$;i-&8TAzN91fSH-zJOkGgp52lCXV$wy z_2P7lBz&BN5FRhSO;V;tpy%YAa~23ktDGL4CzsI7jmarfW-m&4Flpy*2^&R6;Xuks zskC+{cN}ATu$d5x>J{jvfvzONTI(;nLQLySq5m;w5qT1DBHY8XCP|WqoJ=@EIADl4 zg~0>SmuuBYRTcot8z7N)Oaj{Qbk*RaXhDBK>)8n8TCk#cs@tJ6I0Vi!dUc}5;YD#P z)In7J&w|*0YH-t`>}#0WKWcHZW?=70#(NOuEgiEQNzHKbBw$I719|O3+F5?)NNjp= zS~J7T9q>E4@c6&GV`^hGebAG4M&j#SYyso1P6y#U2yN|Phrw+&yA-UtrQfDKts*^? zsyAGH5V+f|-R$KJbP*CQIJ?mqPW}X}j3mttgw)-4;NoTmz@b1e93rbv(u|e-LiA6R zyaSne-EOUX7!ID73Mi}pusbKPVQwd9k3)b4lO!cv2N^S8g$abj3s;R9?gna>?v5_b zVA$bKmQ)Xrt!7B?8=Gn5QNSE^IS|k_re{xd7QtqM)-MhIGmp1FUUZW%S=+5=a>cK{ z>4rd#2z{&DyN>!&WG|%d6`FSVAT~9l8&2Ia@ieh`!sAc2TeE40^}iMzIB~%Wb~;+? z_ae|)_&JNnpMaA=<7IA$sF|I3aIzKu5E%}w%bGLqo%FX!DA6hi>IfvNEUg6ugv5)A zg186UH$0mt&V^jIitpnP6qODx*)(EUK9V1Be>i{rn$|w(LC99VAvy_V4Q9WF^C#ee z?me6nDkUtfVv4M+fCJ-?SBlq~9|DT<`}~Ge7yCT5>iAhW99CmIxDg4n9cg(?ndN|> zd=)Ch1AaT+eGnzPOd*^+4URO#pZa}@4vn3%kg}*@P$2Ugpeb+cX9YLBaN6pbO#TEs z)Vv(82&Ios-Zj^V3hJL)!yC}9br;TX-J${OesmkoCt^J205VEGldY2@MsM^4dQ|k*jV|KJxd#MHvf6PB)$)AAxTxA0m zdDM}I^!6MDv&Q+$=|J=y%&sJ^WR-Xvu%U(}XfHwtYr#j2E2#H&cQQ6c)A1v~E`b4V zm|QuGw-YU9fv*lah)kXbEbzvnY|fhI=^tZpX=^cKJc;MAbA$W|Selqn$wfF6PUB({ zQ&$nB0l37(0tW2P6qv@7CJ`pHT<|8|Eho@*@`UAaL81q=VtiGKp);NBgGqT5un-$BzJqMcHatI@ z4iK5*o}^Ys?soNR-G!5gxW2{6dkJ!eXzY2E#FGApuQidk1(K;6*Q++$t^e za>qU8m1r=@a7c`YnwGvb`?5Ca((t2!5nixjjPAiWd)Q2(kC{Lo1#D&{NlJHpFVo{q z8|DsxO4&z0&uo(c+d+tdCF-+?lN*#G)Q!jacys$Hm8srkQX?@!|)U@`) zLAIL5W+AswrrCdLu&#|9k?!FuH*5IhGn~8%IO%I9o3u%9OenoaAvk?V{+~P%^ChC1 zHcg%U1W(8_wL`+jx6th6o@jiRQo$p0L}fKRypwG0)f$NGqpmogMdfNf+hJTQgf6iYC|r)$&c zEQqYftRt@i9x4ArpR0^))rNDXL@to6G3!zW8|dln)fyZo7(aL;JP$tMQ42V&xuJVQ6`7>fyKO3C}OK}~Dl!j)q>TPyGYJ(o^$UQ$*pKeu|6 zXmmLoh9R`1oA#gi;NAl{Fl)OklwzSF89t%p6Q`G+2s;z;py5Y=7wUC7)foj^)_^Vs0Pn=6 z%%DPl(u2c1;8nij$4f+I=#D4Bo(6AjAK6pF7_;Taa8&7yts`U;2jJ*wRXdycrhd()rk0a1p|z)wwUUwwOuhPA4E;ee^&|7B+s`4;eC`$n=U z+i=FHIPy$}$=^@Zn2!kpgRX&RqJ^ZCp$wmW(NMskOs4Y&j=Fl;>DV09yAd<;1A@3g zqk;#H5RcQz0(CHnIfEs;Gk6(+2di;A2$b2UV@P1X95j_P2 z!!1TRE%=xW3ml7y4UI%&?$~j3NUO-RKKg_CC0bfUwo>R{Gz0_P`wSO9!|T%46|YSN7Ls!m#LilQ=!ltk!!%~A zWTj1IQ-2y8xahAuBPMn5tXMGh`_3HlEnu@iaHzHLT?-I~sri7Q6WkUtJ#gp|n0~bu z?pEXBZcrWbqERDWyVa)C6X63?5EIgGd%HVS6Jpz8IA6<~i0|2#)4?Pfn=ASB%CWX? z(;CJze*|my4K<`j!iIng&CFcRaPlqS0o%c$#@ESKT{y!|9Hua|z)uEKOlwA-ZD+Id z3)tszj~=**Y^9)I2mw;`OcuV=`5?@JE`r7|=_Dg`E`5lB(UdHmL{ZiWM-$#aveRx_ z!&-R!$-`$;0&F_qCxEYdHip6Z7I2@tdgSbXk*&Hgr!?xrZ?pxhPL-tbKzWU!b{?1} z>1`SA17g!z4LI532l zt<;*Pssa}Sol2PDOoM>Oi*6>HjL6;BieJjiTqVkFFs~0LaHjkLMa}c|#Um*JDslwy zAel(ZX>};@5azUAu)}|ytl&ZW-URYsQr>MZPAHOCf56=El3ZPk^&8zj$$00z2Jp7>1}@-?`cC8Ky12W5tbn%*Suz`$odGr=7>h|iIjL6)4o znAUgI8je*4qr5%QKPC_GUQK zAmB7GJH45+G(3KFg1boncpz`D+s)~ai%LQz5%nfQdJ(w(&@Le`=By*R9<`Af*P^M5 zT-C%RzGD{}Ov=Pp&z$mx{&o9Jm}1&~+Iy34Zkw96Y1n_E_0?qS3}zYxJk-3r-*%X6 zHNvp(B%r4m>BBT!re~Yi^47k+ZrZPAqRs%(89;K{d+1l;#AfM6K8ToF(NYVhol!f8#&EnlYVah& z$E*+L^H2Z zXyl)Lg)&bGAv|0)pS+I`=6g^P6(nVfG948&p+`0Gmw46gR}0fJQ3sR2Rbh4q`KO|( z|Cv>z-he?#05HOY2z`MB*kN=VdNKVTP#$++4J^-0rboc03PdBohtydXYZgIX1~he1 zGQ%FaBR8bqd1|EMak5oG%RNTGr=xv80yNhTJP~;wKP65YIFnchLQnJ1BNi7YcaYG( z;`0d@QjZ@F0}a#Jtm3jkd#`MSq2tzHEGhStGv@OeGCcwwJN84e$q2J6HUmDt&Td^` zTGfk^d3C~%$e+Ga-SxiS3TAWw%HcQWI>_5_^SSg0{G&0K%f00YXxUbwtv&MF-$kEX zC>ePN`RCQQM-HVYWp)4lon`p$h>ksb^;`AtZqFkzp4#s(kfC<7WdJ-CR5#{?2!! z^PiR!zuoYn&nNJ?_nsV##r5nke0FQIz4AKQI%9xf`1v)XrmEE*DVOaw{J#37njrMxym+RaX%cYV3;ouEWUCQo z_Z-!7p$*d*62~YM0^ZM*F^`AGj(iut7okkOGV!)`Kz#}X=Y|2Z3VaEMUm6(UeIC}( zR6H*1+aLY??<3#)Uf}Ah!KPu za3=o1X`!yIkGah^0-sFQVN0sppy~H(hTqr>VR{4%#>#AY$~4d_3WMhuX`%Xkeh@G{ zp@#{c*BxqJ-si5y?v&B52SmTR4)Sak?5ctQPf3>=FLms7x#+s^G~H35J`{uNI`;hY z;ma-y{=ff6>XtsvJva2Z&&8g7R*p)i4|wrShlX~a;F@%4bM^Ux2_f~%q~T9YOfSnegDUV{sd8=X1g~3`I-UENjZBY# zCAseTU1Spn%v7otKCh1+`NWMLZ5~08pm3deh&Y7(q$}ov!gZv@lY%k?JwLn?`jaBm z#Ia= zwj&Ll5&Agtybhg7)S?)<^UmP^{lBC#`H%O#FMQKY)9Xu1%FYiSf1=yLUi_f;r^rw< zzfu)b)?&JtHUZ0(u>>xi5OC&)B}GDn6mdm?t4uqVbnzN32;Y0ax_`KC5#9pQ(lNg} zcQFw)HXny}wQdH}`NzL5ow;SvXPyaNcp<4tv&XsT#-4bBeCp|7OYzW(-NW>E3|)3> zV>8@%VcjT1!gLRg!<_mu)0j2^kDmIiVdZ2drus!fW`>WA@@?x*r$FR^v7Tdi3$wll z!c^uNA?K@D`b3~iI4GR(P~d$M-vHCO5S`A@r$0@qF|8x?@sH1hyfjeW*dGWb@Opmm z9afiBoH%p@zJ!|A{vF4L=nM!!w#NT*$FvE!-&&LmGfavhI>MkKMw0O0mNsZkdymy3 zr*?^U8ZdfhO{j{XT}V*}ov|oM`A(oyfOk%G4GwDk6Ehthoi{J|p%2k&Oy_v_yQ4q; zG5G@1L@b_wkhryb%AJO%IXazaoJku3w zoZMT7(u|(DPrWVZ?ue&sr()bk5Ex!bYB+$;xT34lg~MU8FMv?uf(u9;W^jZ)_OYzY z@i^RZ>c)-tT=v)7zqjrFHjjzjJaE7W(=|O%r`Funx3zd^%8QQ0BH#O-klF+4FMF5? zOq+oF9Vdq?|3bEM06`spq>5vh_2rDN-Et+`lrxhd>)45(tAEPnT{Y~pT(u*uK0+%; zg@ZHe&P!K(cG)f7 zNIE|{qSKySvu~Ixk1Z`+IqLOJY#ZdeR=m`MuS^6C%L?aWM#drlm+JHBRVg%H|Y1J^1t5RbhA^Mx&kP6KB zh}?D?_JXF_*?j2lpZgqAFFM}8=#s~eE+)@2!>O8qjYXs>c6pN%susn_HP?Xe5PIMH zL|4jSzTv|1>1EmkEXn(Qn;S<_VWwM|D0L@Q-*UqA1p`4^z;-j`uL$~_rIIl5(+bS+2z~m~*sGc5E31Bhs}~)YEdMrno_Wd| z`dd>sVcJqW)ZNt+-@G~Ut#6?>AG!T@`~<_`WqO%T0gqIsIpm=4BH}=_iCk7ZG9-gQ z1!j7dhM7VeFTO1y$hm8<_B!4H|Jx=obqxjl0kmB>XJ-+<=ptHy86KgJf1G?7Gkj|4 z4YYtiz4WGbU)xdZ(REGhdO~dH!VrHj@#6Z?%I2x^TBmCV_8b#}ius**|L=RBV8=WZ zzQAg_m`(wYAO5!40?`Oi5j}}Y3w5rN+Cnc00Oyl-jAExCB=Dlhyxe2 z&YT1SG?Judu;8*La%&vk)c-$UvQlQ(SqkV$#7rsC% zFvBDCiBBZ`Z6jsB|DU)2Y5dT)#*f_jw}aP@mHcA#^u5ECe;%q|JlL{gpnG4x?QqiH znhY|Aro9pWPj~+QUzc3-iPx^Za^+n}z4~DaxkZ5teL1O6n>P^i7)PVYxj%`ZCM|9+vVi9CDeF`WYL?>RnPBiBqz1ODZj;4rI+ zCGejKuM%t{TK|tAGMI-)goX`U`qRhYDC}|C?_H-~Dd#^3Cjs zW;P=_5f6e^`&?zR)Y~_JhKDQvGE)8+NPXFD7(e`N`8aq3{0WV47n}g6!O61J zU1jiae2fE3F&Jdk*#<)m<{H|C%F2*-5r7%1BazUDKTKb~=^yWT zkC-=~Qxs&Wd+I>9V5nuO*E|cR8w@y@aWLj!(q+RA=KavEveZi-f_swPnW09eZh z?(^1EE@4I#HI_3nKj z_5S^TihR~!`J@^Pq%r$7KTNZL)7UFmg|kzX7rQGOh(sbp5Q|2Sbjmd%gm_%b$Cksh z)^%F;8D3Y%^yLVxfM4q)0Is4#5c1KNZ#u`j-!1IgMZUm{B=U=2gw8#eeE-Dpfe*w_ zosyKUUq72LT}-ophw9UxAIIZcDyicT8cCuBpULbi6}(1#)-gNyq;AoKBPfd>!LQa@ z+5v>W@)h#hP3y>T4p!a}Etb&dKTp4Z`UqWmDS8Nf{mcZWS-|p&LXmC0vI3G88t|km zV9+xAoJ2At%AGSQe$M-%So2z`{5j5TwFAZTo9 zA)k6i5}h|Mbj~^SM_?Qu{9yc$yp@+uE^r!|W&saZ&F^>0E=n4}#j52ls;IFmeeH(B zVL8IoxZ+jdB{ZW@AvS*KTV&%ThVRV~5HS6=b%4*J-(|qF=?rN)*RBnI{iGoK;fzxENj_+s)YW(?CTU?ufW)`H_ltMW4fj3=^S;B3?WkKN4X zgG|I&`2TP3%%kL}$^|Y5CGVgZK|QF?xS%{9B1;G^h#(lE@Z3e82h@l9Ko5wD`cwoF z1%k*PlMo0b5SD;!AqycpAu~xPv-WiNbWhLH(`!|C*E0KL690MM?K^Yl&fU7It9qs| z{!aZdbGy2`y6S%STkdzin{9ZKZS{|eg9}4>oukU1k42&dy&xM|;CA)gaD$)*#$gwS`_3=TapFQN z^cA3oHrhEsklCbmOY(wjYD$J;E*b;U3m&p8pbFX>S=wvXXzzbN--#6m*xscTE7*?< zD*1T4it1n5$tT-xHo=)OW?z6uT9&e{j)5MjFfvKjWT{x>lNn{cD~)XS2s6I@2Pij) z16*!dT-rH!3YTq_V>#RS+b%E3NF|fZ*oR}(a6gmXJ!XAiOBPXXRidgKxI;{w1e3ovpcH(bItItKcpEW(5g!bvrVHrJcpU%{eQ z3nxaHJBb1Rd3@{l*w)#jx4XwlOwKNs#VY7Jz1$x>5t7Y?O!elYj?(7M(@*`+;zy1vEnR9*_c_QwA3#=^uInHEFfX4@4!93RO;gXP&pfj& zz$lmF4{Vbga#`^jJ<~9VMgm!-y=733pl5iU%%Bbk$=q+h+@y+&5Ex_w8IL)+=P1TX z_L z?dUtrQ_h(_e?C9WKD*4m03X_VMZaFX4c0B13c{%i_-{UeCe@o%RE@+ao)gZm8g0A_ zuOh4w&MOw!ZqzRU9QD-tO&ynAURtu8Zb!y*vFIc}9HiqPFP(3f@38kht7-uZ;;l{1 zos+)Os@{Bac@su(H!24FWH<~o%owvTzz6sI2Gx|Rmhxt~tQ8H9hiG8z>ykxz<-In$ z6h+eQ@}NBAt(dAq@$EvK`11^4gMgJ$TK%{!O7=pTgUT5x z%)!@wHq^V*u4)9SH88BhNJQUBtvt}f@2WU_D}a&Rt#?yXW?z5@w9bBml|a9+CTpGd zOqMuzvUCBhp_k0H*pt%5t6yQw^y+YHKP#?Q2q_^1HwV-a>E(3XJ07k4a|U~NkMFvM zZJll4=R`y8;np_tyVfMN?$X5Hu?Sj7=ml46(Q8cr1UMHNj!zUxsSYM#SeT&&3K>;Y zFYhFjPF3)_75W5ga?rhpxZM@qs!av1B4G+^Uq(KcFFo{#oz20mgYUu`$(+6@lG!{} z#y{3wU|R;`N{ib-)tjkY~+D_K4ys-#?0H>SAcm9}dbpxZXKtzd$!^8~1 zRf|PCob*c}=47p@!PGwRfl0gNrbd_VxU!#N6ax#;0uy8MT_hS0zm7>7bz-fI)!#T2 zUuSbqVOD?vsJ*$BHvXHmsc4**%PWRv=fEKDeV*ShW?z79vjCldZFGYyAOT}7{lGw& z6-(*}vU=!txvvY=Eb@vgO-eZj>{wSrj4Ra_3rEf77N!xt5tJ}ry9XqpqPaMbX&K-8 zU0YT2V1_Wzs?Vu9{=jo7eP?cB41%!<2co?L8a_A$IszcTC?88KfzF|OyliH;yWB^G z5=ankDU30xW$}l$e22bff2}fCs!Y1jLW23qt7iRPrV$3F=KTkRBbSpQ@9@i?w+-Di z3|UpMS_2o^-qOaeHp^0>fzDXm$05ewC+>wn2=L*J|HU@Bgg9^Xt_w`G5N|$6x3~iO zH|YU~*Ih)~t8hWpRGg!xac)0@{y~G6#9C4O3iXg@mlt&phu2t=9gJrHaN`+?dO58p zCZkq%xhFWuoOMn`=VE8P{@c%7_lXr>zijQbRqxE^gg^-Jq0N`|7gfs!Dncd(NJnJs zXB%0M5%qnCx5%tQD-BrM;A{O#PD+mk$F4&2Nw9Dg~zNgM=6J&1NlllY< z=`K->2hR*MjWh#V=b=}=VLMwN;v+E9MMGgeB$+508`D!kEE2i!kyKxwBLD369n1gy zp7U@;>$ly0#!2^I4R|m@RbdUw*3bX>LSTvp&hx$P{anK%qJ6P|$(+lktmsOz6WolpIn<3fL!%xZ5 ziWd`)#+;9d4uMftrqV(866wXqQMY{bhcEn&JBE+66jLzLvJ4Iw zJ^2Yd-%;$Ou`OGCkQ z7Ew^YOy>p(;B7b2AiKOd0Eo13rxh=N9l?8aGGz7wA(zR5Rf7Cp zx!sWvc@3aN`P^m@Y_-J!ZZJ5*Y^$$;c`wuOyK}|Xa-K6yEE45^onOGc6$T)_{?t#7 z`SZlqe$2kc? zU!|HjH0t5QG>q<8+^n0ZOD+U{g~DQ2yBj>i;Wc1J!DsUG$-V&QmCT#%DVa|u*^j__hasg8N~o=;2foLf(Qcpsa1>lZ;0;KN*IqFW+u?Kq_YB$>9Bp-V;D!|F^a z;gi5HL;i4d?P%j&pvfyLz$$P)C}dJ;h0Tu*W1K9>zUB;2wvkYnnG!Fli$WPXnh0Ka@O z+vJkMWCV*T)U4||nOPNf`dl_Aw1tEWb~K<6FNwkZF;1>*|0<6AiV?7FRau#_C@7nZl6meZ_(kV2n_Yx&QazLAJ?nf+D~} z-P_nEH&~`g=6D%(iX#4#@+mB%A?wHRM*gLdwukw^k1v=$mBItrEo4+h9^Ya8i>`CMLMEi?3p?Bqi)UZ^r7Jpf(7VYidH%Gm!z3l$p0 zTWPulhN||KHf9nS{*_**WuV1Lepu09EAd}V6Dk<=LIncYQ~ayx#0eOT{Zsr zKu`o26}aelmTh$m*0G?$5|cY2VS2lJWY!l(q4fB%zrUF7-|*=Ma^)n{LiArlZiP283R&_eB>9WMb)@(rd39o42s7 z93YeGde;nSv83Y#PeZ*s55D#@w$(AkLb0v6RWU%QVTSJ+0Bi)AhDc@xu3vq`n9yDT zp~WeU%8`)&9y=gQ@*&s~;c-SU#51fUUus26(Q^>T>i6RRGp3 z<2WdEY`IXDr8q%GsZgl6kRwqvmWXt(U5?BvVtX@BqIclePYkiGeiIl0HVcQgUcojx zgDgb?dxlOJO2j*PCyMU<{Hquc20jdv&*jEnT4i86XsX2Kj^cOjTmvT=|Gtf$t-=89+PmVIX@y*_^$FlzIw`DYAxD8jqi z6dAnX`6EdKqa{A>4OHm*c>E(-2l$VKWb;Aj^l(1tG1+u3ua@C_FwRHX9)g2;$uDGP z7y~0eS}Ijq`XJq+#^JXpV9aKeN-esLV-2?rN7p*BqG9~?s5wcV>?|TQM)tK1-n8yW z(!d9IT{DDWj2$L9|gS@?H;_p!Ip$Td9vw@ zFImdni79D8!2(g=9msbadiC3ikWwa{2F0s>Mwq;5-JMWf_RJ(*sSz4buQv_dyrG|M z^_u_*@MzOLLtUHMRwXF(I_Z88yB7MncpDvw6Y#K&qv_ml~lZXk%OS`PhdB=D{q|K7|!d)^P z3NZbPN{_9vY2}N42+>WeMU*K?fam4# zqh^IIb;Gy5DjjkZBp)e=FOngoJQt%?aHLdI>)wV#*y(oU9{^C1M7Xdk*gY zIompe;1UH>HiFAiKC+)&HJwz{R~YT@FC-6d`Z6QHV9N+?A0ET97I$XwW+*}|v|^$1 znvEHQkLPXNJ#yQ2aVPYV00}TW@iVX zw`h46>Dk~qmR{Z<+|5XVVHg#|yl%r z?(vFeEyPQ7RstJ$)1H+N0*(N!uWS>xHf++ICA&oE@i=U67CyGZ} zmf5C2&v=J_@Io@_42qm5y3C!s*w-rIe1LETJ*Sn=<@kF((!P4M=^hw#GO09Q;zI`L z-oHt5tq8eHmS5^PyYObnvs*^)+9Q}=@|R!iBEQif{8 zf#>48N8k(0EdApfN0;ocxs4Dk0Y-r$$BGWmp2Op$*Vf>h2zIh?&QqxFEYW6YOm&{I z`rp(4`iPTRP#ARdh6BcPFR(8-pr)D%9zn~2silid4~BcFZ@RA7Gi7P3ff1LlYsJ&q zG1Ds+9K!Ujht`ce+;oI#;PGA84CEqgs|eW=klyZIlpCO|Sp|=u?$%&DGr3%F!nB8B z=>4Yn>pYUpWGe1#1g2?0*WFGU%^0*Sk;On@vBPK;|Chk4UOyz&furDYe8o;hO1|R#Ag$rwlDJFdz^cdL!w zN4dIILePo@QD`GL(4o-VpB&xLd4y?Tv>bfTZ`f8jVEWQMgBD;gv}pIzoUT-{eio)) zf$hiil7Z}0;*q~7tU)9UN;4r)z*7LvCE6YaBZ!GG4Rvoh_`0f$$<}Nk?4WD~$cB@E z-|RxGjXyp%y1lpZ@A62n1i0VG4M(40TRDg>rDpwXi}#ky;lVXmxVKBcuB=HGc%b5@5T$PZHb2f%nS*rAkMS`C5cz z7iNC@$#i)WZ9XfAmzJT#rm?+$U>bb^&FhK`Lg)lA+?aLsR#P)(^G@&t7_Avl^;)6d2nHLktgt;J44)XKQnH)PixA3rjWQ^0F3g5O z6JXE1h$oG}<*Pz~k@+fFiRCXa(1f`nI3T4h<(N6Lr6-?Mzm~{FU!%`_F6Fe`DoRA* z%%UJee)Z3nk0q5EDZUUm0j^m25%+uO4Rm%MIADAx5Uxwk3$|UJMrQV{{Zp>FpPFm`xfgTPxc2zX#ywiK_tQakg^^oj4u9Djl~cdqvC zcWWQ~pgw+9LKyutbD@-gAIFa8oZ0UilIKA7CYwo+gp1MO--1x5H-Uku0q zpNfQo&vZ=1G6msi8x?}?JGA+mY-?>mwKcbFrxz+z7jzX`96r*M=xROCq)yL-(U1&? z)`0{1qD9&XC*ap;<0|QZ-=yM8groFt2@Zv>`NDYY`5d z01sqZhdQVFF$1xm$+Qskl~7Bo&;W+h_%%jwKJJ2wnIytUXyrh@CKX#~2N;Bz_gaM( zfg1Q-wVOJID{MW`$S*k(W15BE->ALkJ-mE6JhXSdv$S|I`>}5X8tV6LUbg|B#nty7 z{Plf@*_Zt$Z~|ZG75bl@4A2Ycv|CoiTaDqasj5gFn z3DDb}BBOM-%I9|ok}+P;-lLt_7u1mfMA|+GQyc$4d!jVL)@*ab1D! zXBc`C?O`h_Fwyx8?TV0kudyDN(WggjQEpr3oL_P+PAa_HrlJGZcCkzM1sx{qv+ z?fKFZSIxWk{I}k*;N5@y-tHb^KZ7l;Nrq?Q zLlSjOK4Ict(~PvWDWlJQ`|`wujjl zloWsTBmLA~+3#tub4MP_qkA5^xEZ-#cdk1 z^Ls4)r9+z#^QD)N@yv;zFNgNAkC{7a@+|zKPfwq*>`QZQJ&l)Me9XD+W7luI zoqd~Uf+)aa^*0T5p)ddq@92Vvc1*7RWuQ++ivzhVON=mfP3SLzo)nwkUI6nL?a=+S zbj=2zk)j4%-zqe=jP68NxUJo_HEtOCS!Zd-AJ5C4KgTi0fN^e1yrCfQl_#!#`yFTT za!VhehyS+cG4`F_2%-Rk^bYp!W*V{Ih!-J{7GeAe1eTu`P9>+6-p0W#^`r}oBW#l& z#G)NmUA-mQPXI2StifK9zVN}aC<3=qbuRqPiBgPrmE z)0cgTmstMzk0lp(=Ge~Zg&+#BZ5d4T2uwumtkScivSQ_Y3NdIEW?B{OaQI9`tY{z` z8sGi{w$(G89dW&v%?zUf5pu2l{2-goL_=YPOQJ?U|9tK3Z|9}X&*SK$krECh*Svi5 zyY4)P7gzo`WyzwOx8BFT-vdDu;DLN}eA|_5YZ+qnLRS-RXn-QroB(uniZ_5%Fqmml zcpQ7%XK0R|0xc*7-h173JQtK80xn9$VZ>$8JMFnLZSN1{+DFw6G| z16fD=WjhCJ`|i5E3Iz*4(0To2yX*+y%$BMFp^Zm7WH-SfrRB>D=bz8Zo9~By`swgp z?AHf?^H%;hFRQ}is6U;2@#_C!-|vAy3NXkIRf7tYE!i=YGzz_6TQq|T)-pZit7|$r zhfnh$pkxxux6p1jlgYkbXJ@m*+-w3|s#^{01*=?OS$#=PC|-TFK5rf`Z~h;1<^*#- z>7rHN1IgsYl|N4S%h^YO2Da_d19$QfV7jaE$-^?RUng9AYg4mL42Rc$fo<}D)zxJ@ z`80OSzFq(T1!GA>K~&r74H${4mOT(%FjcC4JA;1Vg& zK5X~`vtR^Sq|+5{S%+yC9Ot>cE%a(*9U-|@%r;teuo!V{y1~_ zmydubv~7>HuE5KHj8X|(xg=x-cCWDSf&lPKf0;A+s&~Sfq~X{Lt~Pm5km`sVPp!p& zqczNu@xtaVwML|qDY`zkce;v3?3_>Xl2)TbKkF>^3WC8mpT72#C5w28rH_;Dzi@f| z6YM*^5l{iP%|gF{bY`(!I2JrZQi&4&mf5`wApGP^(0;;Qn1zde#&`Z?Fnxe+bxEmM zgu~dp#V$<wT)#Cq?@O;xCg$g_~649WvqgN70!EMT-ndO z9iaxkx4pU5m4jW8v|;_FGlO+`@w)3~EQl4%C^QZD!#`ek)BFd&^3ewtp0@OoOCJB> zvn?Chll&u~0&JIM81x31(4ag?#D&+r7~ZI6!qjj=E|cZ8T(P|KJ>4>x+;edE&*>Jo zpjcYTu%>^kuIs!tK@i5|glKuqxeW|9NQEVn)zVWkNx`SmgAe9UJdqbR|BpFy;Jc<@ z$dOKP1$eZ1!eIbyMshO}@dTe}#jkT<1XY^|L1+0&?lw0ljI=IyxIdGS-tL|PRocpT z_&A)5Y&z50*zDHWu1Mar*7i-i;Z|?2e$q*-u+`wu-uqsws!fvri3zR%AAWfe){R7Z zL8->t1%51Vf6^^rB;!bxg*I4WMcw8tQbVsgg#$jytgAQo?q^?^OePbec!@`5gV3Nj zpI%^pmrtxoY6Z>&sNF(B`p{25o%!B>5nKT-?7maWqIEW8re|Uu{B%sTrRB8XP%fLL zck!TwR@kSRnWTfeuc!ZYPES`iA4tQPXcuy+159t5s75#dF@Uez*3_(C>RcTlx8VA+ ztz}Ag-<^N!TX~W5^EmqG;_d#gr+uRnTmd$VdC-Jl{gNP)F#AdO~i1x9voeMl}QcK`zHJiv(1FLEC^J zr91YKm<>Nsqy|)?aN35?tOg+`q1r=RE~ghlIl)Z!l^$BjwoXTu!U6qWZ4nT7>x0l8 z?+i7!y1hTnS=F2GlWfujZa+PSTA>iyLWL7QkB4^LaaOa}nfZTK{vSL(bV#i%)qVf~ N002ovPDHLkV1go(^OOJp literal 2836 zcmeH}c~sL^7RN!x+7To(Wfakg*m}e>MWqMBgKP;HNsvI&ib5@7 zwJsoAMkqvxG1MSSSb_}_TTB8I2(lzWD1ngt!um@>$THFSd;ajxIj85`_s=`;-uvG7 z-OqjR#t9^1%jO-Mt*orJg#9!4q?MI*;Jfkh2FuK`~0L-BN_FH%coy0TuPu+ULayL;e_Qdmsjo( z>^Em1W7fNizWKE55Bq;s;7tLYPWQ%1kB~H~#l=h_kw_w~2RMv7NT{tY_0uF034uV+ zXf#JhM_G4%8qJW1sa_KZ1TS73t&-BCnf`gYMNm0HXx$4#C{EYLP>n_-8`SA^216(O zJOJuJrHs4|4Avr^$4mNLabBSjQN(t_ldWa`Uq`|KZV?3Cne+2m!JU1P6;+j$Ltb2) zY(&HJT(im8S!*aRiSGe(2PjtR3ezVeBDG4T5(b!6;yTH_nW)#`n3m^ExqLh}irLg8 zYAtE3*;T7lDoyEoV0a`?IZ-%myz@xWU8VM%r#J_YC$PS}4&nmV?>F&e;0mFA#9DX? zbuV^`a1Wld{CikeFgBw49+1&bKUL2v8G1dig={jkAN=gUQ7XY$bH5uWJwiZ}%z5!` zdEp|Pi05(PAD1m8OIevPz#*^u?JaPS+0SJD_|$e1)0E}$53`uBeo8TA_tH?*mbh@k z&J8BrQWCru)!_eGOAzq{3#882dcwu86p9p&HduQ+uIQsw*~SVe6go^R%*C6QXZo-5 z`{tB_jWqCQs=UBh*)Yfz+I#&mx!OP!(pQaA*S(Ud$@ zA4~X&AJ=zB?>Z{=Li+`7+O!Fn3&2)2K2taot1--t2vu708lpoY7B4L=Ei#kFN*;K= z&v8xhkTJvR?IgW{PR-A!CMJnQb3^Ny9WOCM(-M0Iiik!ckz+fzH7dWW@accEomB>8 ztQ;USoIIkssx%P4$PVFQV7~+Sy(sw2Xz^L4XM zk9~d04c)DB&aEdZpfThj#jqIJ+0A7I>an0aC~^v~PHs&#|t zAk>;$Ub5zh7l-uxCH#Myfqrw%|IrnVR=e337l7;pVh*qOv zOIr4^acAZ!!jnW%E#imj0E$Tij9VIsY2>1J>EYsM&d$ywVPXuo?y=o`AZ)zzzU;C5_(^3RMk?F7 zN|Wq3l2l~-#;?BLzq~(pz&_8dxO5tR5&17BXVe0u-g`I_FP+@(y3iKrF)J?LhIhb| zH{qn63M!%NR%_go#sEN!V(r$tP8LC&{qyzBi7o+ox`E0-G^JF2{3Z&8Dk=c=zRNGO z<>~oGkN6A$19m{}A~)EV<5DPQQ+~(GM!g7Y^t8Ri*|00oNiZa5RZ1ay1uiI0yXZ{^9s}~ZA;d8=HP_+M*akEaPdg7xFw*c;a*Q;F1 zWlurvk$_5d87}ag$jUM1c^u|mm{m28Gro4fV~5@~D3Td5pb7alSOw+w z`qoUpnj};EUA7%vSi?W7jhw(VeFgWYm<&@>HTJ6+Q!BGV&^^5^iEp+%0~!OS>aEU) zHWn8B?1s+>J(0tPHMq{U;$&XT3p^eVuqTSBc}iN$yTAvYr7GsH)=Bh&^4ex^^KPyCWJL^x=$n|(IJ^^Q-q41D`}(G~?%b|!>p6+{ zDgfeLM|&%kQTM&}wZqotNMy1U%eLo#`|jkV9gFCr*@wUh~{x`R!VTg&>2U9y@#WKVolN#{d8T diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html index a4e9178..0b94de8 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_byprojectmodule.png index 2118a1dd3503f221f7315f7d5eb7813db7ff241d..20774ee54677adecf1e3ff7bb48fbe81f64cb283 100644 GIT binary patch literal 15761 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 G!2bgf-^BX> literal 21825 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 diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.html index 00f0eda..65f033a 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm.png index 69d0377d41f707c176de778296c6d5d1292d71c3..c86796cf92fadb67209a36ac1833c4bcfd40f788 100644 GIT binary patch literal 24072 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 )0 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 literal 24091 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 EKPn1Wu>b%7 diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.html index ca31d2e..313904d 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance 1.3.9.png index a35f4c002a42681c71435df2a37ffc0b91dc609b..28bb0b249eed337e9de5b1fb2d63a7a156bd8ec7 100644 GIT binary patch literal 9547 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 hpCA6e@lb~%8KUkJg0x4L1{U1(ncS8UG literal 9958 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 JTF&Cre*uwFDI)*? diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html index 154f96a..8131653 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.html @@ -1 +1 @@ -CodeMR Software Graph
    \ No newline at end of file +CodeMR Software Graph
    \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png b/SerialX-core/codemr/serialx-core/html/graph_htmls/all_nm_inheritance.png index 7dde07f1fceb14eaced91c600383cab7c9aadae4..af4a3f77ec91f69881f8769d3da08be220677034 100644 GIT binary patch delta 8225 zcmcI}byQSgv@ZF&-q z-h0By&(1NGag|SO0G;YfIXz#q-8npyN9*@^5J-Jp$HM;a zH|56KkckOyetIwc^8953aBw+;_q*LnK)J5G#hG#_sO zz(k}5DwK%bbCh(SCcC#ob#5DTc%GRYLgh?TFrofHgW2d$_i6@UPq zbfJ?>aM)3{&lFhqmrlzO;jLIj{>DNsB4Wi{W1{W7r*7~C>)yL-ua4X#Ei7r^*P)Q! zd)qq#D0Q|OL2laNVuV8fL7sq}PK@4QrmO}j$26LcRZhUG`=z&(`L?6n$UI#x|8u+j z`S&Hd%3fO(h!CC?>b3q9=I*Vvnt}&#nX3qSHU@ zi=0~d?$xgQS1AJ}8%@6~Tr1BLHPMfHD#~)Bz6Jg!{w|x2irZt6I}@0HP;hX_%&;H# zEyzcHVbZI8@awzzEQH7e@0$5N3tU4uaQkM3u2=5F_<77yLE6;yn_@@c_nU~Ykxa>K zUgNV{b6o{p1%1bqp)I)`3_NE#EjO%LU!l{j5u{f)#bxb?+a5*qtL%TkT77<&x6rjY zzCP%F2{IpP5clf@BAaxdD#u#v zYly0g+oLAZ2eYTacEDE^PI?ASx1HzHeY0Yv=6+jggI6b$*9Bt@-BhD-FcED0?^9BChxdlkHX=nDJ#h-2z4=P-O^Ox&%`ld#@Q~KM};StH)%uw z)3r^#L-10xl(x54z3D7QS8*t3$F#bM!sXAf+oH+VmnYwYgU;ghwfp7~n+BK-uZ1$& zFc*?_^bh8IPQc&pI&Zn>Lu zKcCSKARA>4w)^&+5E80Lvn$bobtYs6P0ku&(L%<8V` z#qm(e!Z^+|1Gun2%ZvTY6h%@KQ7*0%b#RiJBI)8ZxT~NiqmpC7&m8&QLkhq0>L&qS zHi1YS?coaUgXV;paFXeOo~m@tTs@qoozEnQ_Bz0+)MHzCbvW;YCln>!%u{f*+prt_ zu7%7aD7O)x2g?` z8F%cO><}5#FN}9wA5?}9k(Dd}1{aq`?pSkg>v{^2=V?YUbz98@GE%hl?#Jb1C}ef1*F7| z2WtxR%oP0LzbNL!;|fNNtzBm8VL~_z9SbNuLNL0G!#6 zhb;Oz8(MH&rza>2Je;l2xTUzJF!~C|;Hld!tU!UY-fiMm`)URd@kD14O`_QmC!(EV zdC$Q7{%1oz9i~0LpdQhtm#V)inFd_27V-pD*;+m3ox`xeK4SRS^&{b z?0sGe{~^p&t|ZrhOG<80nGg&>;onsh;DX(H=hu~wg3s)_c$=jmFpT$n&grx2&F1B` zU@+o}#lF3>guCNID^ULI71tM!I{(IXNaV5WfW8 zd0S13Doe5bIN(M|r$=A}Jo88j=ol5)N!~58;{C%7PWo=(e&B2p!oj|L4B#Ks>ZRpHD;q${&~(k$Rhl2zep>FIX#@jv{0 z=Ps7>Jh5iM#eHT4P?MZ1Qge)Ze)RSmf7Qx?gr&gcba;ZJQVPOQ*fp`|XRn}$L+q)1JfSN z<75cZNa&XIo5gsaH-6;|3&Z~K7iNL|;Ha!UMkF+LrSi2Ypdwx};JcBYHJx~D+>CQT z4BDwb`?;UvyOboZF#m+X0a`Kr^fTRaT)7vpIk|e_^X>fOOgQ1Y+7^Q!UL9v@@;&W5 zeg;>&+cQB14MYZ;c%<(1&vEY*U^oJDIkR@Z7XKXIwya%jY;P)>dUrC$4#uYTuxDC{ zv%d*6u;~~U0uGo!yuR@L>m&1+ACE^%;ct+n&FSv$DaTby_$vK2XnaXAsY=F* z3&%1%M-y5bEwNMPqhB@hIIyOui+8!s0uHhWp++L?#*G&@hcd=@*EiLSr_^3S-kbdb zZnO>3;U9A^(#z6Oji_Ay8;Rpt4IRYU2@7KThw?lF&=@2IM%^17>8#X6ijyMp_CrYU zhVqK@63eEXqMc4k-wXPA!d9cRUTrIne_mG)xPg zIgt|`$366i?m4F0Fg+z1ANnJm_E2s~?N%Um=G^vYUF3Ou%k`fSZKqBr5`kA=)j=9o z&KIEu@5~2d#U&k>5bHJZ+h#$w-PfFngCnJFv^jK(yo%oWtBC2Kw7eXnaZx_;?D>IL zgcD(G!QgKpvgQ{?xkHcF?KYgUedo|oEsU0EVVX9Rp}G2QsefYW z?o^f>ni(L=d6+UufmQSE)YDM~C0(=iNOjUNy3E8170!sVl}c~bpAVP643cF25c5CH z7#DdQTSL|Zbc}ZR?`<9)9)9fAJ|9`h2RLwxMYmRFSELVrs3z{-;hV=Fa@=!N-{)Mr zbg%`}`Mra6@7!kH3JDt_8n*Th9_Bo_+l^b|6x;?$uXNv*yefzZ0 z!tH;JK%O{;tJE`8t5bNjtP;oef_n21L8i#FcPbGmQuEx5>StEHZdFJIBvd1nZ~4BC zoa>Tng=YRj)po@^*R&hDVEk;?L8>?%QvcjIS#McN*n#lj?#l*MHu4HCO$ z16Ig*Cf#>GR@oJ93}^(oS4~_F1bKp4cj$gl>j$Q2Hd~D{>-KYfW2(3lWwsDtq*xrC zTJ@3dre2qQo}a`64d2Zgw$i_+^_Zb4Y-p>_!2&HXJH^#|KaQC;Q-U)9{*%><6U3>l*pg$6sJONfX(a1B1Qte1S%%7Go*1i)1N?^9jIgZ|8o z|M~E78k2*w!xOAKAZ?aRZW~$V-(GYKCkSB?Cq3};^PC>BWG`0Uq;%yJ(mK(6$;pk{ ze#9}lJ0N%t!1ljJ+XwC^?q2ci3ivCg@R~hJe4@ozwY}`^6mdEuCL=L_l4giXpu;sR z?HQ)BNmKhxx&D^sqdQ%MP8z^4Z^ksI)lRDwx6@ZtCJ};6_J~@EGrRiql7E`EVIqA0 zlLne!`G8AR39#!&wzsHn-@0HQVMphJJ?Y+nk){T`Nr^ZS7)%)9nKhNa>(n1T4~~9Z zt9FJYwta~BlURFG`@-Q%Q;2Jw(yhJK@Q4i^nSCsr;PU7|OLVPXlu@`$1UZ+7ebONY z&Ba(yk^E*ms#cN1-CjQ9oLJm5%X_I=Amlz=>chU@N7ZYGE*C>q8`1jlHMl1Fw z8#cwiqvA5LF9xIB8`@hZtaiTnLy0`Zqs3|0xHD|h-)g`YzfbpJc*AZdNegB$#oI|M z-(>i0FX<%>Qqlpt)wuBFwg1$-iBqCMkh&%9pT8a(vt>{;WT~!9*1G$!xz# zM$_P|!&5$!Ko}*iqtF*mDzJ1L=>PZYck)bYsAH8PTgRMOoI^eLm&+2^ki4Dsb4xFL zUeq5@Q@!AM>O0!Y5HmdQ&K!B?_@?5{MeI<5$~T>}&t-v2wAkq4ip>#yqrMg&ZubLu zm}p62a>rX+JJmk~{*)4o0q9Rug;ek74y93@O$4jVm<8^oo0N+$ISSEtyE_U^Jpiyw zvRHX21tv=<-)5N{!g{%Wu0gWi5>IrGVWfSFNM&I1k~TiyVOk{c(2e}{SEi1}xvK`l zX}ka!^=fFhAMOuf8qj1G>;6;RX~8FhW0>EXaKkC-%&%j7Xd(cq=0+>2pvm{@6DQf+ zWgdEDAT5r(Q=U!eb7_0tf)8;w8_iB~ON~w&=7FV^q@#7Tbaby5Zs?6}4JS|)U9Y=6 zKs{>~g{&=MIO+R!HXWiJ8Q$-n%+96{XfcZ^v!oIKxvUr8e!Fpdco90RR6#5#X~9pn zrwcu0Lx4Vf*+OemdviJxHXOcHqj-)jSsCI4GD!^nob37sk&@Pq1vku+AD9fZ1-xNG z*~51H_y@ltryGU>i-IoFACf=g*Nu!joxQV$3(4OjAcU1~_>f6b6;f5dO&yl6h0Ms*Os*?xjiw6> zdj2T$>0dUyyjKoxe0=IL{kQEcE>itthdZIrRM;wp(}dACLE~&TllCac2zi56Z^{_SJFC3E{ zQD{VL?I&#J9s#m)Zp5$UWW&<6ZQ+Tn;(XP3r)=X|ULSRL9wxol)-pCEhWL2D(VRp~ zac;(8GDi1345FU*Q1bb*xay)2=(k^w=tbNux8QmXa6GuynAQ z&fXKJAgV;aeWR88sj8$2mGHsjrRr~y@_;{-jSZdd*3(9!M&=O>=FALQZe(jlq!8`S zy5akt=d-}a;^}d94%Pjik;7_ zjIkaTr4oWD|McPgcTs*{x&H1Jvz4hXj+lObc&sQJgI9w_a9RkHCagZX1Irm^yd}}| zFNdk7vp6a@coa_@G6lQbagzomVBrOlIrFXK(1_Q0eDYf|n6^ykbyPr;1nP@P0#Z3_ zN0$2~t*sQ7HyKAnh{uLYEf{o*_0?x}{Cjh7{%83|g3{G^bAuD;29j{|qBz0SaFd;L zmw~m0Y>W;Aj~^fMz;(x!^Y`jVgBG$-Ldet3H!aFilO!RX&GAvH?OaVvR(KW}Tq|8d zq*+|j;!dV|CUok7y|DK%dgAySz&0fN_@>H8bt|EI8J=*GNKC!?ydg`vx8`2psKAZ& z`B3~GXCl)#aSZX*J`C!=f9)o9sPD3A484o)%PZYtGW7iUd>N_n&|IkNB5%|UXlo+r zD?iEh4xKn2=(XSRjO=o~ypm@5YeoU2?3aYHNA z2YolaFerVg79-R~75d{pHs|ntH}J)Ej3q?T=isJ49ZX2*a43J9w|dsY>jM+wu6zh! zl^JAZzGi&*nzrGy*64e(PLx{K~Kj4oC?C&PKFTI1j4nm;Y13jsgWfSuOjK%r{r zC>VG10{)2fI$oQ7Es7)JT8Ekjo`^tCi+tEBF}CMaNVveyTU5%w860F;cNI1Jmpk|6 z*j{lZbwHf9c5QU2c;eYS;q~{OgGJ54AS8*C9FDIYMULqDgAWWA@4=j130d#-i4pBy zI}%C-`P!yPsyEzb{_Eq$w#-<)xhwW_w^*Vj#I~bk+Cj47eFqfUVC_lFD@qhYlPWBV zjw_;8<83c6p{qzMiWqF#5mmCC{gucf`{|yIXw#c=i~v9i``CHH_gS0oDMSS2gCkur zUHgJSWd__v`i!IIKBXAzrFS$bm#(R<1h3oX&;et+QMeXox?t3+vnlH2d3Vtu4duBj z73>!YR+%!Xd4D{q#|cdxpS9kGU0d+17z$V1nhLn#n^A!(z~k7B5P9?~fcD%f+;yMj zkJ3;!8$m>e2rJEcCz5ROuAiBnJp|Y4O_>JlX5-Fga!=t z*BerFw?-#u4__--6ru{xap)MZT%1>^aVVA&E)ML)MU=3Np)YSmBHJC zjtNCJl@{aC-41%uf*LI8-KzduhpvwbgkoGxv)(2KhX*q=sti2Rd{~!P5oQ)&xZ{sY zMgqy4c>gcxlB8WyuXD`D<`}dh160-UZ{?*bpWi8PBbr|st|&KP0X`ovjEivlZ{Yp; zZs9{0>plzMZsjzlt^S6qRd^}~h(3Pv17jPy=~)Wb{@3)Rmg0V5T}KvdtA=|Ow%*k6 z-zDv{{?Nv}V=f{4=gJYd7fFj5UW{f<+Fo%p=V5OWg4a(1&Vl3BAV(=Oyei>j)tawZ zu}p|-mzRYHWq?I9LnA90$w5r<+7T7hb=;-pHB7qF4g5}oM}lWM_WHUfkuBY zmn+6j@jRPx!lT0XX-?g?BpQ;RQ;6IKLs1yRTLtM;_4U7CPKwRFZ)y6$Uz9t;=*J+; zcn8tzxDx6KyU0sTq^QF52>a>mDC3-1JhRJ5oYx~NJnrlR&<^p$#O@cc?4qlDlkXNXm7EGNQ@Cie{f?@+3ra6onEIjnFA()&&mO{MsqVusyY0B?5xgcSEGLs+_HP0 zoD}86EO-5_NY25+T*HZohlbE8z%G9Z<(n*akz2@A??0t(6v9qNqM70B5n`@^1LB|| z#`3T*%zP7zhaldkG^?R~ue@_fac#TIsL%%fJ%k&-lp4I%?&am!E{XwtCN41f)3d$ztC%Mk zqKsd;SRR#&B0Wex@cyrNbaZYdJkJN+l+b;T9>w?oyuCAHymHBTesR2EKvw% zl&k#b09RFDc3bx4xhY2w-57y1-v8Ws;(sqa{+ksCfZmJzHzfaGDS-c>b*zGwF? Y&Ic{VjnAww(2uGj?yHv-@)n{03;L1D-~a#s delta 8225 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
    +5}!dl$Vx-^>>YixI}^%gtmZ7IJX8;Hctr>h}R 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 XHT&(Kc`$x>xSyJ`_KWK0Rv-QYR}Ib= diff --git a/SerialX-core/codemr/serialx-core/html/graph_htmls/graphlist.js b/SerialX-core/codemr/serialx-core/html/graph_htmls/graphlist.js index 7a46a2b..4dd3c2b 100644 --- a/SerialX-core/codemr/serialx-core/html/graph_htmls/graphlist.js +++ b/SerialX-core/codemr/serialx-core/html/graph_htmls/graphlist.js @@ -1 +1 @@ -var EQ_graphHTMLText = '

    '; \ No newline at end of file +var EQ_graphHTMLText = ''; \ No newline at end of file diff --git a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js index 35f59bd..6ad1b4e 100644 --- a/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js +++ b/SerialX-core/codemr/serialx-core/html/html_report_serialx-core/htmlx/modeldata/sunburst_data.js @@ -11,52 +11,52 @@ function EQ_GET_DATA(){ { "name": "ProtocolConverter","key": "y","value":157, "metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, -"metricvalues":{"20":7,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":7,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +"metricvalues":{"20":7,"21":0,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"33":7,"34":46,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} }, { "name": "SerializableBase64Converter","key": "B","value":37, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":3,"34":24,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} }, { "name": "DataParser","key": "E","value":117, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"33":0,"34":0,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} }, { "name": "CharacterConverter","key": "G","value":20, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":2,"34":10,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} }, { "name": "NumberConverter","key": "x","value":88, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"33":3,"34":15,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} }, { "name": "VariableParser","key": "D","value":42, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":5,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":5,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":5,"34":16,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} }, { "name": "StringConverter","key": "m","value":51, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, -"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +"metricvalues":{"20":3,"21":0,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"33":3,"34":18,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} }, { "name": "DataConverter","key": "P","value":13, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +"metricvalues":{"20":1,"21":0,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"33":1,"34":0,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} }, { "name": "BooleanConverter","key": "Q","value":29, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"33":3,"34":12,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} }, { "name": "NullConverter","key": "L","value":17, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":3,"34":3,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} } ] },{ @@ -67,32 +67,32 @@ function EQ_GET_DATA(){ { "name": "EnumProtocol","key": "N","value":12, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":3,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} }, { "name": "ScopeProtocol","key": "A","value":17, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +"metricvalues":{"20":1,"21":0,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":1,"34":6,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} }, { "name": "MapProtocol","key": "r","value":25, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":2,"34":10,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} }, { "name": "SerializationProtocol","key": "t","value":120, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, -"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +"metricvalues":{"20":1,"21":0,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"33":1,"34":14,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} }, { "name": "StringProtocol","key": "C","value":33, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":6,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} }, { "name": "ListProtocol","key": "K","value":16, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":5,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} } ] },{ @@ -103,17 +103,17 @@ function EQ_GET_DATA(){ { "name": "LogProvider","key": "I","value":20, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"33":0,"34":11,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} }, { "name": "Registry","key": "O","value":125, "metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, -"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"33":0,"34":27,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} }, { "name": "Utils","key": "w","value":346, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":1,"28":3,"29":5,"30":1,"31":1,"32":4,"33":1,"34":2,"35":3,"36":1,"16":5,"37":1,"4":3,"8":3,"2":1,"3":4,"1":5}, -"metricvalues":{"20":5,"21":0,"38":13,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"39":4,"33":5,"34":85,"40":9,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"33":5,"34":85,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} } ] },{ @@ -124,22 +124,22 @@ function EQ_GET_DATA(){ { "name": "GenericScope","key": "M","value":333, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, -"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +"metricvalues":{"20":5,"21":0,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"33":5,"34":79,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} }, { "name": "Scope","key": "s","value":353, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":1,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":1,"3":4,"1":5}, -"metricvalues":{"20":5,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":5,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"33":5,"34":106,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} }, { "name": "MultimediaSerializer","key": "k","value":25, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"33":0,"34":0,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} }, { "name": "Serializer","key": "J","value":212, "metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, -"metricvalues":{"20":8,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":8,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +"metricvalues":{"20":8,"21":1,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"33":8,"34":63,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} } ] },{ @@ -150,12 +150,12 @@ function EQ_GET_DATA(){ { "name": "Import","key": "H","value":48, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, -"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +"metricvalues":{"20":1,"21":0,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"33":1,"34":10,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} }, { "name": "ImportsProvider","key": "o","value":84, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"33":0,"34":0,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} } ] }] @@ -202,9 +202,6 @@ EQ_METRIC_MAP["Simple Response For a Class"] =34; EQ_METRIC_MAP["Number of Static Methods"] =35; EQ_METRIC_MAP["CBO Lib"] =36; EQ_METRIC_MAP["Number of Overridden Methods"] =37; -EQ_METRIC_MAP["Degree"] =38; -EQ_METRIC_MAP["OutDegree"] =39; -EQ_METRIC_MAP["InDegree"] =40; var EQ_SELECTED_CLASS_METRIC = "C3"; var EQ_SELECTED_PACKAGE_METRIC = "C3"; var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; @@ -212,7 +209,7 @@ var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; -var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods"]; var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; function EQ_GET_COLOR(d) { diff --git a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js index 67e8693..baf8eef 100644 --- a/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js +++ b/SerialX-core/codemr/serialx-core/html/main_report/htmlx/modeldata/sunburst_data.js @@ -11,52 +11,52 @@ function EQ_GET_DATA(){ { "name": "ProtocolConverter","key": "y","value":157, "metrics":{"20":2,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":3,"27":1,"28":3,"29":5,"30":3,"31":1,"32":3,"33":2,"34":1,"35":1,"36":1,"16":3,"37":1,"4":2,"8":2,"2":2,"3":3,"1":3}, -"metricvalues":{"20":7,"21":0,"38":1,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"39":1,"33":7,"34":46,"40":0,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} +"metricvalues":{"20":7,"21":0,"22":3,"23":0.0,"24":152,"25":0,"26":1,"0":3,"27":10,"28":102,"29":0.962,"30":0.8,"31":0,"32":0.712,"33":7,"34":46,"35":6,"36":0,"16":74,"37":0,"4":2,"8":157,"2":2,"3":3,"1":3} }, { "name": "SerializableBase64Converter","key": "B","value":37, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":3,"34":24,"40":0,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":36,"25":0,"26":1,"0":1,"27":3,"28":37,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":3,"34":24,"35":2,"36":0,"16":12,"37":0,"4":1,"8":37,"2":1,"3":1,"1":1} }, { "name": "DataParser","key": "E","value":117, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":4,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"39":2,"33":0,"34":0,"40":2,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":2,"25":2,"26":1,"0":1,"27":1,"28":2,"29":1.0,"30":0.0,"31":3,"32":0.125,"33":0,"34":0,"35":1,"36":0,"16":2,"37":0,"4":2,"8":117,"2":1,"3":1,"1":1} }, { "name": "CharacterConverter","key": "G","value":20, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":19,"25":0,"26":1,"0":1,"27":3,"28":13,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":2,"34":10,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} }, { "name": "NumberConverter","key": "x","value":88, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":2,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"39":1,"33":3,"34":15,"40":0,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":87,"25":0,"26":1,"0":2,"27":4,"28":20,"29":0.0,"30":0.0,"31":0,"32":0.622,"33":3,"34":15,"35":1,"36":0,"16":50,"37":0,"4":2,"8":88,"2":1,"3":2,"1":2} }, { "name": "VariableParser","key": "D","value":42, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":5,"21":0,"38":1,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":5,"34":16,"40":0,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.0,"24":41,"25":0,"26":1,"0":2,"27":3,"28":44,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":5,"34":16,"35":0,"36":0,"16":24,"37":0,"4":1,"8":42,"2":1,"3":1,"1":2} }, { "name": "StringConverter","key": "m","value":51, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":3,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":2}, -"metricvalues":{"20":3,"21":0,"38":1,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"39":1,"33":3,"34":18,"40":0,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} +"metricvalues":{"20":3,"21":0,"22":2,"23":0.0,"24":48,"25":0,"26":1,"0":2,"27":7,"28":31,"29":0.786,"30":0.6,"31":0,"32":0.661,"33":3,"34":18,"35":1,"36":0,"16":26,"37":0,"4":2,"8":51,"2":1,"3":2,"1":2} }, { "name": "DataConverter","key": "P","value":13, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":3,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":1,"21":0,"38":9,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"39":1,"33":1,"34":0,"40":8,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} +"metricvalues":{"20":1,"21":0,"22":0,"23":0.0,"24":5,"25":8,"26":1,"0":1,"27":3,"28":5,"29":0.0,"30":0.0,"31":0,"32":0.3,"33":1,"34":0,"35":2,"36":0,"16":5,"37":0,"4":1,"8":13,"2":1,"3":1,"1":1} }, { "name": "BooleanConverter","key": "Q","value":29, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"39":1,"33":3,"34":12,"40":0,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":1,"23":0.0,"24":27,"25":0,"26":1,"0":1,"27":7,"28":18,"29":0.952,"30":0.0,"31":0,"32":0.595,"33":3,"34":12,"35":0,"36":0,"16":20,"37":0,"4":1,"8":29,"2":1,"3":1,"1":1} }, { "name": "NullConverter","key": "L","value":17, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":3,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"39":1,"33":3,"34":3,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} +"metricvalues":{"20":3,"21":0,"22":0,"23":0.0,"24":16,"25":0,"26":1,"0":1,"27":3,"28":7,"29":0.0,"30":0.0,"31":0,"32":0.267,"33":3,"34":3,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":1} } ] },{ @@ -67,32 +67,32 @@ function EQ_GET_DATA(){ { "name": "EnumProtocol","key": "N","value":12, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":3,"40":0,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":11,"25":0,"26":2,"0":2,"27":3,"28":6,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":3,"35":0,"36":0,"16":3,"37":0,"4":1,"8":12,"2":1,"3":1,"1":2} }, { "name": "ScopeProtocol","key": "A","value":17, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":1,"21":0,"38":1,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":1,"34":6,"40":0,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} +"metricvalues":{"20":1,"21":0,"22":0,"23":0.0,"24":16,"25":0,"26":2,"0":2,"27":3,"28":24,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":1,"34":6,"35":0,"36":0,"16":7,"37":0,"4":1,"8":17,"2":1,"3":1,"1":2} }, { "name": "MapProtocol","key": "r","value":25, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":2,"21":0,"38":1,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":2,"34":10,"40":0,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} +"metricvalues":{"20":2,"21":0,"22":0,"23":0.0,"24":24,"25":0,"26":2,"0":2,"27":3,"28":25,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":2,"34":10,"35":0,"36":0,"16":8,"37":0,"4":1,"8":25,"2":1,"3":1,"1":2} }, { "name": "SerializationProtocol","key": "t","value":120, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":2,"26":1,"0":3,"27":1,"28":1,"29":5,"30":4,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":3,"1":1}, -"metricvalues":{"20":1,"21":0,"38":6,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"39":1,"33":1,"34":14,"40":5,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} +"metricvalues":{"20":1,"21":0,"22":1,"23":0.0,"24":36,"25":5,"26":1,"0":3,"27":8,"28":36,"29":0.97,"30":0.933,"31":4,"32":0.75,"33":1,"34":14,"35":4,"36":0,"16":16,"37":0,"4":2,"8":120,"2":1,"3":3,"1":1} }, { "name": "StringProtocol","key": "C","value":33, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":6,"40":0,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":32,"25":0,"26":2,"0":2,"27":3,"28":9,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":6,"35":0,"36":0,"16":12,"37":0,"4":1,"8":33,"2":1,"3":1,"1":2} }, { "name": "ListProtocol","key": "K","value":16, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":2,"0":2,"27":1,"28":1,"29":1,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":2}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"39":1,"33":0,"34":5,"40":0,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":15,"25":0,"26":2,"0":2,"27":3,"28":8,"29":0.0,"30":0.0,"31":0,"32":0.5,"33":0,"34":5,"35":0,"36":0,"16":5,"37":0,"4":1,"8":16,"2":1,"3":1,"1":2} } ] },{ @@ -103,17 +103,17 @@ function EQ_GET_DATA(){ { "name": "LogProvider","key": "I","value":20, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":1,"30":3,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":7,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"39":0,"33":0,"34":11,"40":7,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":1,"23":0.0,"24":17,"25":0,"26":1,"0":1,"27":4,"28":15,"29":0.5,"30":0.75,"31":1,"32":0.5,"33":0,"34":11,"35":0,"36":0,"16":9,"37":0,"4":1,"8":20,"2":1,"3":1,"1":1} }, { "name": "Registry","key": "O","value":125, "metrics":{"20":1,"21":1,"22":1,"23":4,"24":2,"25":2,"26":3,"0":3,"27":2,"28":1,"29":1,"30":1,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":2,"37":1,"4":2,"8":2,"2":1,"3":2,"1":3}, -"metricvalues":{"20":0,"21":0,"38":2,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"39":0,"33":0,"34":27,"40":2,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.552,"24":123,"25":2,"26":4,"0":3,"27":29,"28":40,"29":0.0,"30":0.0,"31":1,"32":0.626,"33":0,"34":27,"35":0,"36":0,"16":49,"37":4,"4":2,"8":125,"2":1,"3":2,"1":3} }, { "name": "Utils","key": "w","value":346, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":1,"28":3,"29":5,"30":1,"31":1,"32":4,"33":1,"34":2,"35":3,"36":1,"16":5,"37":1,"4":3,"8":3,"2":1,"3":4,"1":5}, -"metricvalues":{"20":5,"21":0,"38":13,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"39":4,"33":5,"34":85,"40":9,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.0,"24":344,"25":0,"26":1,"0":5,"27":1,"28":116,"29":1.0,"30":0.0,"31":1,"32":0.811,"33":5,"34":85,"35":33,"36":0,"16":188,"37":0,"4":3,"8":346,"2":1,"3":4,"1":5} } ] },{ @@ -124,22 +124,22 @@ function EQ_GET_DATA(){ { "name": "GenericScope","key": "M","value":333, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":1,"0":5,"27":5,"28":3,"29":5,"30":2,"31":1,"32":5,"33":1,"34":2,"35":1,"36":1,"16":5,"37":1,"4":5,"8":3,"2":1,"3":5,"1":5}, -"metricvalues":{"20":5,"21":0,"38":1,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"39":0,"33":5,"34":79,"40":1,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} +"metricvalues":{"20":5,"21":0,"22":3,"23":0.017,"24":328,"25":1,"26":1,"0":5,"27":60,"28":144,"29":0.979,"30":0.55,"31":1,"32":0.91,"33":5,"34":79,"35":6,"36":0,"16":138,"37":1,"4":5,"8":333,"2":1,"3":5,"1":5} }, { "name": "Scope","key": "s","value":353, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":3,"25":1,"26":2,"0":5,"27":4,"28":4,"29":1,"30":1,"31":1,"32":4,"33":1,"34":3,"35":1,"36":1,"16":5,"37":1,"4":4,"8":3,"2":1,"3":4,"1":5}, -"metricvalues":{"20":5,"21":0,"38":2,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"39":1,"33":5,"34":106,"40":1,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} +"metricvalues":{"20":5,"21":0,"22":0,"23":0.041,"24":351,"25":1,"26":2,"0":5,"27":49,"28":173,"29":0.0,"30":0.0,"31":1,"32":0.894,"33":5,"34":106,"35":11,"36":0,"16":175,"37":1,"4":4,"8":353,"2":1,"3":4,"1":5} }, { "name": "MultimediaSerializer","key": "k","value":25, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":3,"27":1,"28":1,"29":1,"30":1,"31":1,"32":3,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":3,"1":1}, -"metricvalues":{"20":0,"21":0,"38":1,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"39":0,"33":0,"34":0,"40":1,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":11,"25":1,"26":1,"0":3,"27":11,"28":11,"29":0.0,"30":0.0,"31":0,"32":0.742,"33":0,"34":0,"35":0,"36":0,"16":11,"37":0,"4":1,"8":25,"2":1,"3":3,"1":1} }, { "name": "Serializer","key": "J","value":212, "metrics":{"20":2,"21":1,"22":1,"23":2,"24":2,"25":1,"26":2,"0":5,"27":3,"28":5,"29":5,"30":4,"31":1,"32":5,"33":2,"34":2,"35":1,"36":1,"16":3,"37":1,"4":3,"8":2,"2":2,"3":5,"1":5}, -"metricvalues":{"20":8,"21":1,"38":2,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"39":2,"33":8,"34":63,"40":0,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} +"metricvalues":{"20":8,"21":1,"22":3,"23":0.265,"24":206,"25":0,"26":3,"0":5,"27":34,"28":215,"29":0.986,"30":0.813,"31":1,"32":0.901,"33":8,"34":63,"35":2,"36":0,"16":79,"37":3,"4":3,"8":212,"2":2,"3":5,"1":5} } ] },{ @@ -150,12 +150,12 @@ function EQ_GET_DATA(){ { "name": "Import","key": "H","value":48, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":2,"27":1,"28":1,"29":5,"30":2,"31":1,"32":2,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":1,"8":1,"2":1,"3":2,"1":1}, -"metricvalues":{"20":1,"21":0,"38":2,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"39":1,"33":1,"34":10,"40":1,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} +"metricvalues":{"20":1,"21":0,"22":3,"23":0.083,"24":44,"25":0,"26":1,"0":2,"27":12,"28":19,"29":0.955,"30":0.667,"31":0,"32":0.633,"33":1,"34":10,"35":0,"36":0,"16":20,"37":1,"4":1,"8":48,"2":1,"3":2,"1":1} }, { "name": "ImportsProvider","key": "o","value":84, "metrics":{"20":1,"21":1,"22":1,"23":1,"24":1,"25":1,"26":1,"0":1,"27":1,"28":1,"29":5,"30":1,"31":1,"32":1,"33":1,"34":1,"35":1,"36":1,"16":1,"37":1,"4":2,"8":2,"2":1,"3":1,"1":1}, -"metricvalues":{"20":0,"21":0,"38":3,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"39":1,"33":0,"34":0,"40":2,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} +"metricvalues":{"20":0,"21":0,"22":0,"23":0.0,"24":6,"25":1,"26":1,"0":1,"27":1,"28":6,"29":1.0,"30":0.0,"31":2,"32":0.528,"33":0,"34":0,"35":5,"36":0,"16":6,"37":0,"4":2,"8":84,"2":1,"3":1,"1":1} } ] }] @@ -202,9 +202,6 @@ EQ_METRIC_MAP["Simple Response For a Class"] =34; EQ_METRIC_MAP["Number of Static Methods"] =35; EQ_METRIC_MAP["CBO Lib"] =36; EQ_METRIC_MAP["Number of Overridden Methods"] =37; -EQ_METRIC_MAP["Degree"] =38; -EQ_METRIC_MAP["OutDegree"] =39; -EQ_METRIC_MAP["InDegree"] =40; var EQ_SELECTED_CLASS_METRIC = "C3"; var EQ_SELECTED_PACKAGE_METRIC = "C3"; var EQ_SELECTED_PROJECT_METRIC = "Class Lines of Code"; @@ -212,7 +209,7 @@ var EQ_CLASS_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_CLASS_METRIC]; var EQ_PACKAGE_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PACKAGE_METRIC]; var EQ_PROJECT_METRIC_INDEX = EQ_METRIC_MAP[EQ_SELECTED_PROJECT_METRIC]; var EQ_COLOR_OF_LEVELS = ["#1F77B4","#007F24","#62BF18","#FFC800","#FF5B13","#E50000"]; -var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods","Degree","OutDegree","InDegree"]; +var EQ_CLASS_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Class Lines of Code","Weighted Method Count","Coupling Between Object Classes","Access to Foreign Data","Number of Fields","Specialization Index","Class-Methods Lines of Code","Number of Children","Depth of Inheritance Tree","Number of Methods","Response For a Class","Lack of Tight Class Cohesion","Lack of Cohesion of Methods","Number of Static Fields","Lack of Cohesion Among Methods(1-CAM)","CBO App","Simple Response For a Class","Number of Static Methods","CBO Lib","Number of Overridden Methods"]; var EQ_PACKAGE_METRICS = ["C3","Complexity","Coupling","Lack of Cohesion","Size","Number of Entities","Class Lines of Code","Efferent Coupling","Number of Interfaces","Number of Classes","Afferent Coupling","Weighted Method Count","Normalized Distance","Abstractness","Instability"]; var EQ_PROJECT_METRICS = ["Number of Highly Problematic Classes","Number of Entities","Number of Problematic Classes","Class Lines of Code","Number of External Packages","Number of Packages","Number of External Entities"]; function EQ_GET_COLOR(d) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java index 57c8d41..aedb77c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/GenericScope.java @@ -1,6 +1,6 @@ package org.ugp.serialx; -import static org.ugp.serialx.utils.Utils.Instantiate; +import static org.ugp.serialx.utils.MetaprogrammingUtils.Instantiate; import java.io.Serializable; import java.lang.reflect.Type; @@ -21,7 +21,7 @@ import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * This collection is some sort of hybrid, or more accurately "union" between {@link List} and {@link Map} which allow you to have both variables and independent values managed by one Object.
    @@ -110,7 +110,7 @@ public boolean equals(Object obj) if (obj instanceof Map) return valuesCount() <= 0 && variables().equals(obj); if (obj != null && obj.getClass().isArray()) - return variablesCount() <= 0 && Objects.deepEquals(toArray(), Utils.fromAmbiguousArray(obj)); + return variablesCount() <= 0 && Objects.deepEquals(toArray(), MetaprogrammingUtils.fromAmbiguousArray(obj)); return super.equals(obj); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index df60437..fbf0b4b 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1,8 +1,8 @@ package org.ugp.serialx; import static org.ugp.serialx.converters.DataParser.VOID; -import static org.ugp.serialx.utils.Utils.Instantiate; -import static org.ugp.serialx.utils.Utils.equalsLowerCase; +import static org.ugp.serialx.utils.MetaprogrammingUtils.Instantiate; +import static org.ugp.serialx.utils.StrUtils.equalsLowerCase; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -25,7 +25,7 @@ import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** @@ -995,7 +995,7 @@ public static Scope from(Object obj, String... fieldNamesToUse) throws Exception return new Scope(); if (obj.getClass().isArray()) - return new Scope(Utils.fromAmbiguousArray(obj)); + return new Scope(MetaprogrammingUtils.fromAmbiguousArray(obj)); if (obj instanceof Scope) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java index bfc0152..60d33ee 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Serializer.java @@ -1,9 +1,7 @@ package org.ugp.serialx; -import static org.ugp.serialx.utils.Utils.Instantiate; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.multilpy; -import static org.ugp.serialx.utils.Utils.post; +import static org.ugp.serialx.utils.MetaprogrammingUtils.Instantiate; +import static org.ugp.serialx.utils.StrUtils.*; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -13,7 +11,6 @@ import java.io.OutputStream; import java.io.Reader; import java.lang.reflect.Type; -import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.net.URLConnection; @@ -595,49 +592,44 @@ public static T into(Object obj, Serializer fromSerializer, String... fieldN { URLConnection con = ((URL) obj).openConnection(); con.setDoOutput(true); - if (con instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) con); - else +// if (con instanceof HttpURLConnection) +// post(fromSerializer, (HttpURLConnection) con); +// else fromSerializer.serializeTo(con.getOutputStream()); return (T) con; } if (obj instanceof URLConnection) { - if (obj instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) obj); - else +// if (obj instanceof HttpURLConnection) +// post(fromSerializer, (HttpURLConnection) obj); +// else fromSerializer.serializeTo(((URLConnection) obj).getOutputStream()); return (T) obj; } - try + if (obj instanceof CharSequence) { - if (obj instanceof CharSequence) +// if (indexOfNotInObj((CharSequence) obj, "http") == 0) +// { +// URLConnection con = new URI(obj.toString()).toURL().openConnection(); +// con.setDoOutput(true); +// if (con instanceof HttpURLConnection) +// post(fromSerializer, (HttpURLConnection) con); +// else +// fromSerializer.serializeTo(con.getOutputStream()); +// return (T) con; +// } + + try { - if (indexOfNotInObj((CharSequence) obj, "http") == 0) - { - URLConnection con = new URI(obj.toString()).toURL().openConnection(); - con.setDoOutput(true); - if (con instanceof HttpURLConnection) - post(fromSerializer, (HttpURLConnection) con); - else - fromSerializer.serializeTo(con.getOutputStream()); - return (T) con; - } - - try - { - File file = new File(obj.toString()); - fromSerializer.serializeTo(file); - return (T) file; - } - catch (Exception e) - {} + File file = new File(obj.toString()); + fromSerializer.serializeTo(file); + return (T) file; } + catch (Exception e) + {} } - catch (IOException e) - {} return (T) Scope.into(obj, fromSerializer, fieldNamesToUse); } diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java index 1d77755..c11efc7 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/BooleanConverter.java @@ -1,7 +1,8 @@ package org.ugp.serialx.converters; -import static java.lang.Boolean.*; -import static org.ugp.serialx.utils.Utils.equalsLowerCase; +import static java.lang.Boolean.FALSE; +import static java.lang.Boolean.TRUE; +import static org.ugp.serialx.utils.StrUtils.equalsLowerCase; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java index 3348969..26238c4 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NullConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.utils.Utils.equalsLowerCase; +import static org.ugp.serialx.utils.StrUtils.equalsLowerCase; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java index c6d323f..570378c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/NumberConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.utils.Utils.contains; +import static org.ugp.serialx.utils.StrUtils.contains; import java.io.IOException; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java index 1a5619c..f128096 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/ProtocolConverter.java @@ -1,6 +1,7 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.utils.Utils.*; +import static org.ugp.serialx.utils.MetaprogrammingUtils.*; +import static org.ugp.serialx.utils.StrUtils.*; import java.io.IOException; import java.io.Serializable; @@ -18,7 +19,7 @@ import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * This converter is capable of converting any Object using {@link SerializationProtocol} as well as invoking static functions! @@ -427,8 +428,8 @@ public static char[] secondarySubscopeWrappers() * @param args | Arguments of method. Arguments should be certain if method is overloaded! * @param compilerArgs | Arguments provided by parser. * - * @return {@link Utils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
    - * Note: If you are not sure what this does, preferably use {@link Utils#InvokeStaticFunc(Class, String, Object...)}! + * @return {@link MetaprogrammingUtils#InvokeStaticFunc(Class, String, Object...)} or null if {@link InvocationTargetException} occurred.
    + * Note: If you are not sure what this does, preferably use {@link MetaprogrammingUtils#InvokeStaticFunc(Class, String, Object...)}! * * @since 1.3.8 */ @@ -436,7 +437,7 @@ public static Object InvokeStaticFunc(Class cls, Class oldCls, String name try { compilerArgs[4] = oldCls; - return Utils.InvokeStaticFunc(cls, name, args); + return MetaprogrammingUtils.InvokeStaticFunc(cls, name, args); } catch (InvocationTargetException e) { diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java index 0487378..d03b8f1 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/StringConverter.java @@ -1,7 +1,6 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.StrUtils.*; import java.io.IOException; import java.util.HashMap; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java index 86f4866..9c51c82 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/VariableParser.java @@ -1,8 +1,7 @@ package org.ugp.serialx.converters; -import static org.ugp.serialx.utils.Utils.Clone; -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.splitValues; +import static org.ugp.serialx.utils.MetaprogrammingUtils.Clone; +import static org.ugp.serialx.utils.StrUtils.*; import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/MetaprogrammingUtils.java similarity index 55% rename from SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java rename to SerialX-core/src/main/java/org/ugp/serialx/utils/MetaprogrammingUtils.java index 4e9bd68..bff082f 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/utils/Utils.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/MetaprogrammingUtils.java @@ -14,11 +14,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.HttpURLConnection; -import java.net.URLEncoder; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.Map; import org.ugp.serialx.Scope; @@ -29,21 +26,14 @@ import org.ugp.serialx.protocols.SerializationProtocol; /** - * Provides general utility used across SerialX library, mostly string analysis/manipulation and reflection. + * Provides general utility used across SerialX library, provides reflection and IO helpers. * * @author PETO * - * @since 1.3.8 + * @since 1.3.8 (split from Utils in 4.0.0) */ -public final class Utils { - private Utils() {} - - /** - * {@link System#lineSeparator()} - * - * @since 1.3.9 - */ - public static final char[] ENDL = System.lineSeparator().toCharArray(); +public final class MetaprogrammingUtils { + private MetaprogrammingUtils() {} /** * @param f | Source file. @@ -439,412 +429,6 @@ else if (objs[i] instanceof Class) return classes; } - /* Characters */ - - /** - * @param ch | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; - * - * @since 1.3.2 - */ - public static StringBuilder multilpy(char ch, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(ch); - return sb; - } - - /** - * @param str | String to multiply! - * @param times | Count of multiplication! - * - * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; - * - * @since 1.3.0 - */ - public static StringBuilder multilpy(CharSequence str, int times) - { - StringBuilder sb = new StringBuilder(); - while (times-- > 0) - sb.append(str); - return sb; - } - - /** - * @param s | String to split and check some syntax. - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
    - * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} - * - * @since 1.0.0 - */ - public static String[] splitValues(String s, char... splitter) - { - return splitValues(s, 0, 2, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    - * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.0 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    - * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.5 - */ - public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); - } - - /** - * @param s | String to split and check some syntax. - * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... - * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! - * @param splittingStrategy | If 0, splitting will occur after each splitter! - * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! - * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! - * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! - * @param splitter | Chars where string will be split! - * - * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    - * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' - * - * @since 1.3.8 - */ - public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) - { - if (splitter.length <= 0 || limit == 1) - return new String[] {s}; -// -// if (isOneOf(s.charAt(0), splitter)) -// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); - - List result = new ArrayList<>(); - - int lastIndex = 0, len = s.length(); - for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) - { - int ch = s.charAt(i); - if (ch == '"') - { - do if (++i >= len) - throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); - while (s.charAt(i) != '"'); - } - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++i >= len) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(i) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++i < len && s.charAt(i) != '"'); - } - } - else if (isOneOf(ch, splitBreaks)) - break; - else if (isOneOf(ch, splitter) && - (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) - { - String tok = s.substring(lastIndex, i).trim(); - if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) - { - result.add(tok); - lastIndex = i + 1; - - count++; - } - } - - oldCh = ch; - } - - result.add(s.substring(lastIndex, len).trim()); - return result.toArray(new String[0]); - } - - /** - * @param s | CharSequence to search! - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, char... oneOf) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param oneOf | Characters to find! - * - * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) - { - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else if (isOneOf(ch, oneOf)) - { - if (firstIndex) - return from; - defaultReturn = from; - } - } - return defaultReturn; - } - - /** - * @param s | CharSequence to search! - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.0 - */ - public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) - { - return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); - } - - /** - * @param s | CharSequence to search! - * @param from | The beginning index, where to start the search (should be 0 in most cases). - * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). - * @param defaultReturn | Index to return by default (usually -1). - * @param firstIndex | If true, first index will be returned, if false last index will be returned. - * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! - * - * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! - * - * @since 1.3.5 (expanded in 1.3.8) - */ - public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) - { - if (sequencesToFind.length < 1) - return defaultReturn; - - for (; from < to; from++) - { - int ch = s.charAt(from); - if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - else if ((ch | ' ') == '{') - { - for (int brackets = 1; brackets != 0; ) - { - if (++from >= to) - throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); - if ((ch = (s.charAt(from) | ' ')) == '{') - brackets++; - else if (ch == '}') - brackets--; - else if (ch == '"') - while (++from < to && s.charAt(from) != '"'); - } - } - else - { - findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) - { - CharSequence currentMatch; - if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) - { - int match = 1, lenToFind = currentMatch.length(); - for (int i = from+1; i < to && match < lenToFind; i++, match++) - if (s.charAt(i) != currentMatch.charAt(match)) - continue findMatch; - - if (match == lenToFind) - { - defaultReturn = from; - if (firstIndex) - return defaultReturn; - } - } - } - } - } - return defaultReturn; - } - - /** - * @param str | String to do replacements in! - * @param target | Target to replace! - * @param replacement | Replacement for target! - * - * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! - * - * @since 1.2.0 - */ - public static String fastReplace(String str, String target, CharSequence replacement) - { - int targetLength = target.length(); - if (targetLength == 0) - return str; - - int i1 = 0, i2 = str.indexOf(target); - if (i2 < 0) - return str; - - int len = str.length(); - StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); - do - { - sb.append(str, i1, i2).append(replacement); - i1 = i2 + targetLength; - i2 = str.indexOf(target, i1); - } while (i2 > 0); - - return sb.append(str, i1, len).toString(); - } - - /** - * @param ch | Char to compare! - * @param chars | Chars to match! - * - * @return True if inserted char (ch) is any of inserted chars! - * - * @since 1.3.0 - */ - public static boolean isOneOf(int ch, char... chars) - { - final int charsLen = chars.length; - for (int i = 0; i < charsLen; i++) - if (chars[i] == ch) - return true; - return false; - } - - /** - * @param str | Char sequence to search. - * @param oneOf | Chars to search for! - * - * @return {@link String#contains(CharSequence)} for char sequence! - * - * @since 1.3.0 - */ - public static boolean contains(CharSequence str, char... oneOf) - { - if (oneOf.length == 1) - { - for (int i = 0, len = str.length(); i < len; i++) - if (str.charAt(i) == oneOf[0]) - return true; - return false; - } - - for (int i = 0, len = str.length(); i < len; i++) - if (isOneOf(str.charAt(i), oneOf)) - return true; - return false; - } - - /** - * @param str | Source string to compare. - * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! - * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). - * @param to | The ending marking index, index where to end the comparing (exclusive, most likely {@code >= to <= str.length()}) - * - * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
    - * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
    - * Also sufficient length of both strings is not checked so adjust from and to accordingly. - * - * @since 1.3.8 - */ - public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) - { - for (; from < to; from++) - if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) - return false; - return true; - } - - /** - * @param str | String to display! - * @param pos | Position to display! - * - * @return String with displayed position by using » or ^ under it! - * Use for debugging or error printing! - * - * @since 1.3.2 - */ - public static String showPosInString(CharSequence str, int pos) - { - if (pos < 0) - return str.toString(); - - try - { - if (contains(str, ENDL)) - return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); - return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); - } - catch (IndexOutOfBoundsException e) - { - return str.toString(); - } - } - - /* Arrays */ - /** * @param sourceArray | Array to cast! * @param toType | Type to cast array in to! @@ -904,15 +488,18 @@ public static Object[] fromAmbiguousArray(Object array) /* Others... */ /** + * @deprecated DO NOT USE! THIS FUNCTION, ESPECIALY ITS UTILIZATIOn IN Serializer WAS DEEMED TO BE WAY TO PROBLEMATIC AND POTENTIALLY DANAGEROUS IN THIS FORM. PLEASE IMPLEMENT YOUR OWN HTTP post WHEN SERIALIZING INTO {@link HttpURLConnection}!
    + * * This will serialize serializer into http query post request however this is not the best networking and you should implement your own http client if you want SerialX to serialize and deserialize remote content! * * @param serializer | Serializer to post. - * @param conn | Http connection to use! + * @param conn | Http connection to use! Assumed to be in output mode. * * @throws IOException if posting failed! * * @since 1.3.5 */ + @Deprecated public static void post(Serializer serializer, HttpURLConnection conn) throws IOException { StringBuilder postData = new StringBuilder(); @@ -920,22 +507,22 @@ public static void post(Serializer serializer, HttpURLConnection conn) throws IO { if (postData.length() != 0) postData.append('&'); - postData.append(URLEncoder.encode(param.getKey(), "UTF-8")).append('='); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param.getValue()).toString(), "UTF-8")); + postData.append(param.getKey()).append('='); + postData.append(serializer.getParsers().toString(param.getValue())); } for (Object param : serializer) { if (postData.length() != 0) postData.append('&'); - postData.append(URLEncoder.encode(serializer.getParsers().toString(param).toString(), "UTF-8")); + postData.append(serializer.getParsers().toString(param)); } byte[] postDataBytes = postData.toString().getBytes("UTF-8"); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); - conn.setDoOutput(true); +// conn.setRequestProperty("Content-Length", String.valueOf(postDataBytes.length)); +// conn.setDoOutput(true); conn.getOutputStream().write(postDataBytes); } } \ No newline at end of file diff --git a/SerialX-core/src/main/java/org/ugp/serialx/utils/StrUtils.java b/SerialX-core/src/main/java/org/ugp/serialx/utils/StrUtils.java new file mode 100644 index 0000000..7d484e6 --- /dev/null +++ b/SerialX-core/src/main/java/org/ugp/serialx/utils/StrUtils.java @@ -0,0 +1,424 @@ +package org.ugp.serialx.utils; + +import java.util.ArrayList; +import java.util.List; + +/** + * Provides general utility used across SerialX library, provides string analysis/manipulation helpers. + * + * @author PETO + * + * @since 1.3.8 (split from Utils in 4.0.0) + */ +public class StrUtils { + private StrUtils() {} + + /** + * {@link System#lineSeparator()} + * + * @since 1.3.9 + */ + public static final char[] ENDL = System.lineSeparator().toCharArray(); + + /** + * @param ch | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy('a', 5) will return "aaaaa"; + * + * @since 1.3.2 + */ + public static StringBuilder multilpy(char ch, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(ch); + return sb; + } + + /** + * @param str | String to multiply! + * @param times | Count of multiplication! + * + * @return Multiplied char, for example multilpy("a", 5) will return "aaaaa"; + * + * @since 1.3.0 + */ + public static StringBuilder multilpy(CharSequence str, int times) + { + StringBuilder sb = new StringBuilder(); + while (times-- > 0) + sb.append(str); + return sb; + } + + /** + * @param s | String to split and check some syntax. + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters. More than one splitter in row will be take as 1. Each resulting token will be {@link String#trim() trim}med!
    + * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '} + * + * @since 1.0.0 + */ + public static String[] splitValues(String s, char... splitter) + { + return splitValues(s, 0, 2, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    + * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.0 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, new char[0], splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered, splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    + * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.5 + */ + public static String[] splitValues(String s, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + return splitValues(s, 0, limit, splittingStrategy, splitBreaks, splitter); + } + + /** + * @param s | String to split and check some syntax. + * @param i | Index of character to start at. Note that everything before this index will be ignored by other options... + * @param limit | If 0 or less = no limit, 1 = no splitting, more than 1 = count of results! + * @param splittingStrategy | If 0, splitting will occur after each splitter! + * If 1, string will be splitted after only one splitter, more than one splitters in row will be ignored! + * If 2, splitting will occur after any number of splitters, n number of splitters in row will be treated as 1! + * @param splitBreaks | When some of these characters is encountered (not in object), splitting is terminated for the rest of the string! + * @param splitter | Chars where string will be split! + * + * @return String splitted after splitters according to arguments. Each resulting token will be {@link String#trim() trim}med!
    + * Note: Splitting will only occur if splitter is not in object meaning it is not in string nor between '{' or '[' and ']' or '}' + * + * @since 1.3.8 + */ + public static String[] splitValues(String s, int i, int limit, int splittingStrategy, char[] splitBreaks, char... splitter) + { + if (splitter.length <= 0 || limit == 1) + return new String[] {s}; +// +// if (isOneOf(s.charAt(0), splitter)) +// return splitValues(" "+s, limit, oneOrMore, splitBreaks, splitter); + + List result = new ArrayList<>(); + + int lastIndex = 0, len = s.length(); + for (int count = 1, oldCh = 0; i < len && (limit <= 0 || count < limit); i++) + { + int ch = s.charAt(i); + if (ch == '"') + { + do if (++i >= len) + throw new IllegalArgumentException("Unclosed or missing quotes in: " + s); + while (s.charAt(i) != '"'); + } + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++i >= len) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(i) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++i < len && s.charAt(i) != '"'); + } + } + else if (isOneOf(ch, splitBreaks)) + break; + else if (isOneOf(ch, splitter) && + (splittingStrategy != 1 || ch != oldCh && (i >= len-1 || !isOneOf(s.charAt(i+1), splitter)))) + { + String tok = s.substring(lastIndex, i).trim(); + if (splittingStrategy < 2 || result.isEmpty() || !tok.isEmpty()) + { + result.add(tok); + lastIndex = i + 1; + + count++; + } + } + + oldCh = ch; + } + + result.add(s.substring(lastIndex, len).trim()); + return result.toArray(new String[0]); + } + + /** + * @param s | CharSequence to search! + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, char... oneOf) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, oneOf); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param oneOf | Characters to find! + * + * @return Index of first character found that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}', otherwise -1! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, char... oneOf) + { + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else if (isOneOf(ch, oneOf)) + { + if (firstIndex) + return from; + defaultReturn = from; + } + } + return defaultReturn; + } + + /** + * @param s | CharSequence to search! + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.0 + */ + public static int indexOfNotInObj(CharSequence s, CharSequence... sequencesToFind) + { + return indexOfNotInObj(s, 0, s.length(), -1, true, sequencesToFind); + } + + /** + * @param s | CharSequence to search! + * @param from | The beginning index, where to start the search (should be 0 in most cases). + * @param to | Ending index of search (exclusive, should be {@code >= to <= s.length()}). + * @param defaultReturn | Index to return by default (usually -1). + * @param firstIndex | If true, first index will be returned, if false last index will be returned. + * @param sequencesToFind | Character sequences to find, index of any of these will be returned accordingly, none of these should contain and object structure! + * + * @return Index of first found CharSequence that is not in object meaning it is not in string nor between '{' or '[' and ']' or '}'! + * + * @since 1.3.5 (expanded in 1.3.8) + */ + public static int indexOfNotInObj(CharSequence s, int from, int to, int defaultReturn, boolean firstIndex, CharSequence... sequencesToFind) + { + if (sequencesToFind.length < 1) + return defaultReturn; + + for (; from < to; from++) + { + int ch = s.charAt(from); + if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + else if ((ch | ' ') == '{') + { + for (int brackets = 1; brackets != 0; ) + { + if (++from >= to) + throw new IllegalArgumentException("Missing ("+ brackets + ") closing bracket in: " + s); + if ((ch = (s.charAt(from) | ' ')) == '{') + brackets++; + else if (ch == '}') + brackets--; + else if (ch == '"') + while (++from < to && s.charAt(from) != '"'); + } + } + else + { + findMatch: for (int cur = 0, seqsLen = sequencesToFind.length; cur < seqsLen; cur++) + { + CharSequence currentMatch; + if (ch == (currentMatch = sequencesToFind[cur]).charAt(0)) + { + int match = 1, lenToFind = currentMatch.length(); + for (int i = from+1; i < to && match < lenToFind; i++, match++) + if (s.charAt(i) != currentMatch.charAt(match)) + continue findMatch; + + if (match == lenToFind) + { + defaultReturn = from; + if (firstIndex) + return defaultReturn; + } + } + } + } + } + return defaultReturn; + } + + /** + * @param str | String to do replacements in! + * @param target | Target to replace! + * @param replacement | Replacement for target! + * + * @return Inserted string after replacing all targets with replacements similar to {@link String#replace(CharSequence, CharSequence)} but faster! + * + * @since 1.2.0 + */ + public static String fastReplace(String str, String target, CharSequence replacement) + { + int targetLength = target.length(); + if (targetLength == 0) + return str; + + int i1 = 0, i2 = str.indexOf(target); + if (i2 < 0) + return str; + + int len = str.length(); + StringBuilder sb = new StringBuilder(targetLength > replacement.length() ? len : len * 2); + do + { + sb.append(str, i1, i2).append(replacement); + i1 = i2 + targetLength; + i2 = str.indexOf(target, i1); + } while (i2 > 0); + + return sb.append(str, i1, len).toString(); + } + + /** + * @param ch | Char to compare! + * @param chars | Chars to match! + * + * @return True if inserted char (ch) is any of inserted chars! + * + * @since 1.3.0 + */ + public static boolean isOneOf(int ch, char... chars) + { + final int charsLen = chars.length; + for (int i = 0; i < charsLen; i++) + if (chars[i] == ch) + return true; + return false; + } + + /** + * @param str | Char sequence to search. + * @param oneOf | Chars to search for! + * + * @return {@link String#contains(CharSequence)} for char sequence! + * + * @since 1.3.0 + */ + public static boolean contains(CharSequence str, char... oneOf) + { + if (oneOf.length == 1) + { + for (int i = 0, len = str.length(); i < len; i++) + if (str.charAt(i) == oneOf[0]) + return true; + return false; + } + + for (int i = 0, len = str.length(); i < len; i++) + if (isOneOf(str.charAt(i), oneOf)) + return true; + return false; + } + + /** + * @param str | Source string to compare. + * @param lowerCaseOther | Other lower-case string to compare with. This must be lower-case in order for this to work! + * @param from | The beginning index, where to start with comprising (inclusive, most likely 0). + * @param to | The ending marking index, index where to end the comparing (exclusive, most likely {@code >= to <= str.length()}) + * + * @return True if str is equal to lowerCaseOther given that str case is ignored and lowerCaseOther is lower-case, otherwise false. Similar to {@link String#equalsIgnoreCase(String)} but more optimal!
    + * Note that this function was designed for non-blank ASCII strings and may not work properly for others...
    + * Also sufficient length of both strings is not checked so adjust from and to accordingly. + * + * @since 1.3.8 + */ + public static boolean equalsLowerCase(CharSequence str, CharSequence lowerCaseOther, int from, int to) + { + for (; from < to; from++) + if ((str.charAt(from) | ' ') != lowerCaseOther.charAt(from)) + return false; + return true; + } + + /** + * @param str | String to display! + * @param pos | Position to display! + * + * @return String with displayed position by using » or ^ under it! + * Use for debugging or error printing! + * + * @since 1.3.2 + */ + public static String showPosInString(CharSequence str, int pos) + { + if (pos < 0) + return str.toString(); + + try + { + if (contains(str, ENDL)) + return str.subSequence(0, pos) + "»" + str.subSequence(pos, str.length()); + return multilpy(' ', pos).append('^').insert(0, '\n').insert(0, str).toString(); + } + catch (IndexOutOfBoundsException e) + { + return str.toString(); + } + } +} diff --git a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java index 2e57938..7f395c2 100644 --- a/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java +++ b/SerialX-devtools/src/main/java/org/ugp/serialx/devtools/SerializationDebugger.java @@ -1,6 +1,6 @@ package org.ugp.serialx.devtools; -import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.StrUtils.multilpy; import java.io.IOException; import java.io.PrintWriter; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java index 5942009..609bfbd 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/JsonSerializer.java @@ -1,7 +1,6 @@ package org.ugp.serialx.json; -import static org.ugp.serialx.utils.Utils.isOneOf; -import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.StrUtils.*; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; diff --git a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java index f2b657b..ea05a51 100644 --- a/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java +++ b/SerialX-json/src/main/java/org/ugp/serialx/json/converters/JsonObjectConverter.java @@ -8,7 +8,7 @@ import org.ugp.serialx.json.JsonSerializer; import org.ugp.serialx.juss.converters.ObjectConverter; import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * Used internally by {@link JsonSerializer} to ensure proper and valid Json format for scopes and protocols. @@ -27,7 +27,7 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj return CONTINUE; if (obj.getClass().isArray()) - return super.toString(source, myHomeRegistry, new Scope(Utils.fromAmbiguousArray(obj)), args); + return super.toString(source, myHomeRegistry, new Scope(MetaprogrammingUtils.fromAmbiguousArray(obj)), args); if (obj instanceof Map) { diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java index a353220..02cc9d2 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/JussSerializer.java @@ -1,11 +1,9 @@ package org.ugp.serialx.juss; import static org.ugp.serialx.converters.DataParser.VOID; -import static org.ugp.serialx.utils.Utils.Clone; -import static org.ugp.serialx.utils.Utils.ENDL; -import static org.ugp.serialx.utils.Utils.InvokeStaticFunc; -import static org.ugp.serialx.utils.Utils.isOneOf; -import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.MetaprogrammingUtils.Clone; +import static org.ugp.serialx.utils.MetaprogrammingUtils.InvokeStaticFunc; +import static org.ugp.serialx.utils.StrUtils.*; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; @@ -47,7 +45,7 @@ import org.ugp.serialx.juss.converters.VariableConverter; import org.ugp.serialx.protocols.SerializationProtocol.ProtocolRegistry; import org.ugp.serialx.utils.Registry; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * This is implementation of {@link Serializer} for serializing in default SerialX API implementation known as JUSS (Java universal serial script) which is Json like domain specific language that has extended functionality! @@ -192,7 +190,7 @@ public Imports getImports() } /** - * @param absoluteClone | If true this scope will be cloned using {@link Utils#Clone}, if false {@link Scope#clone()}! + * @param absoluteClone | If true this scope will be cloned using {@link MetaprogrammingUtils#Clone}, if false {@link Scope#clone()}! * * @return Clone of this scope! * @@ -807,7 +805,7 @@ protected Object parseObject(ParserRegistry registry, String str, Object... pars * * @return Clone of value stored by variable with inserted name or null if there is no such a one! *

    - * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * Note: Cloning is done by {@link MetaprogrammingUtils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ @@ -822,7 +820,7 @@ public T cloneOf(String variableKey) * * @return Clone of value stored by variable with inserted name or defaultValue if there is no such a one or given key contains null! *

    - * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * Note: Cloning is done by {@link MetaprogrammingUtils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ @@ -840,7 +838,7 @@ public T cloneOf(String variableKey, T defaultValue) * * @return Clone of independent value with valueIndex! *

    - * Note: Cloning is done by {@link Utils#Clone(Object, Collection, Object[], Object...)}! + * Note: Cloning is done by {@link MetaprogrammingUtils#Clone(Object, Collection, Object[], Object...)}! * * @since 1.3.2 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java index 958aabc..3000737 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ArrayConverter.java @@ -1,9 +1,8 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.utils.Utils.castArray; -import static org.ugp.serialx.utils.Utils.fromAmbiguousArray; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.splitValues; +import static org.ugp.serialx.utils.MetaprogrammingUtils.castArray; +import static org.ugp.serialx.utils.MetaprogrammingUtils.fromAmbiguousArray; +import static org.ugp.serialx.utils.StrUtils.*; import java.io.IOException; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 1c45de5..63e9cf9 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -1,6 +1,6 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.StrUtils.*; import java.io.IOException; import java.io.StringReader; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java index 06a5225..58e1d0b 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/OperationGroups.java @@ -1,6 +1,6 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.utils.Utils.isOneOf; +import static org.ugp.serialx.utils.StrUtils.isOneOf; import java.util.Arrays; import java.util.HashMap; @@ -111,7 +111,7 @@ public static int isGroupMark(CharSequence s, char groupMark) * @param from | Beginning index of search! * @param openings | Openings to find! * - * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first opening char found if is not in object or -1 if there is no opening found similar to {@link org.ugp.serialx.utils.MetaprogrammingUtils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ @@ -148,7 +148,7 @@ else if (isOneOf(ch, openings)) * @param openings | Openings to count with! * @param closing | Closings to find! * - * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.utils.Utils#indexOfNotInObj(CharSequence, char...)}! + * @return Return index of first closing char found if is not in object or -1 if no closing is found similar to {@link org.ugp.serialx.utils.MetaprogrammingUtils#indexOfNotInObj(CharSequence, char...)}! * * @since 1.3.0 */ diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java index 0f5287d..9b58683 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/VariableConverter.java @@ -1,7 +1,6 @@ package org.ugp.serialx.juss.converters; -import static org.ugp.serialx.utils.Utils.contains; -import static org.ugp.serialx.utils.Utils.splitValues; +import static org.ugp.serialx.utils.StrUtils.*; import java.io.IOException; import java.util.AbstractMap; diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java index 09f6ae3..cdf7c4d 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/AutoProtocol.java @@ -12,7 +12,7 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.Scope; import org.ugp.serialx.protocols.SerializationProtocol; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * This is automatic protocol that will automatically serialize every or selected field in object that has valid and public getter and setter! @@ -125,7 +125,7 @@ public AutoProtocol(Class applicableFor, boolean useScope, List applicableFor, boolean useScope, List objectClass) throws Exception { - return Utils.Instantiate(objectClass); + return MetaprogrammingUtils.Instantiate(objectClass); } @Override diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java index bd81085..483bca7 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/protocols/UniversalObjectInstantiationProtocol.java @@ -7,7 +7,7 @@ import org.ugp.serialx.GenericScope; import org.ugp.serialx.protocols.SerializationProtocol; import org.ugp.serialx.utils.LogProvider; -import org.ugp.serialx.utils.Utils; +import org.ugp.serialx.utils.MetaprogrammingUtils; /** * Universal protocol for deserializing any object using its constructor. Args array of {@link UniversalObjectInstantiationProtocol#unserialize(Class, Object...)} must have elements applicable as arguments for some constructor of required objects class! @@ -46,7 +46,7 @@ public T unserialize(Class objectClass, Object... args) throws Exce { try { - return objectClass.getConstructor(Utils.ToClasses(args)).newInstance(args); + return objectClass.getConstructor(MetaprogrammingUtils.ToClasses(args)).newInstance(args); } catch (Exception e0) { diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java index 63ad024..e04d25a 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ArithmeticOperators.java @@ -1,7 +1,8 @@ package org.ugp.serialx.converters.operators; import static java.util.Arrays.asList; -import static org.ugp.serialx.utils.Utils.*; +import static org.ugp.serialx.utils.StrUtils.*; +import static org.ugp.serialx.utils.MetaprogrammingUtils.*; import java.util.ArrayList; import java.util.Collection; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java index afca4d6..828e40a 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ComparisonOperators.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.StrUtils.*; import java.lang.reflect.Array; import java.util.Collection; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java index 554f2f0..765da78 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/ConditionalAssignmentOperators.java @@ -1,6 +1,6 @@ package org.ugp.serialx.converters.operators; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; +import static org.ugp.serialx.utils.StrUtils.*; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.utils.LogProvider; diff --git a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java index 1a17f78..aaa8c8c 100644 --- a/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java +++ b/SerialX-operators/src/main/java/org/ugp/serialx/converters/operators/LogicalOperators.java @@ -2,8 +2,7 @@ import static java.lang.Boolean.FALSE; import static java.lang.Boolean.TRUE; -import static org.ugp.serialx.utils.Utils.indexOfNotInObj; -import static org.ugp.serialx.utils.Utils.multilpy; +import static org.ugp.serialx.utils.StrUtils.*; import org.ugp.serialx.converters.DataParser; import org.ugp.serialx.utils.LogProvider; From ed4a29f61cdcd18aee4c4bb035c888e1f12d9c83 Mon Sep 17 00:00:00 2001 From: Programmer001 Date: Wed, 30 Sep 2026 17:39:50 +0200 Subject: [PATCH 75/75] Javadoc completness improvments and Javadoc fixes --- SerialX-core/src/main/java/org/ugp/serialx/Scope.java | 2 +- .../java/org/ugp/serialx/converters/imports/Import.java | 7 +++++++ .../org/ugp/serialx/juss/converters/ObjectConverter.java | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java index fbf0b4b..1e89fa9 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/Scope.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/Scope.java @@ -1325,7 +1325,7 @@ public static List intoGeneric(List listToGenerify, ParameterizedType return (List) listToGenerify; } - /* + /** * @param listToGenerify | Map whose values should be modify/map its elements into specified type. * @param genericType | Requested type of lists elements. * diff --git a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java index dca251a..f87aa0c 100644 --- a/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java +++ b/SerialX-core/src/main/java/org/ugp/serialx/converters/imports/Import.java @@ -111,6 +111,13 @@ public String getTypeName() return getClsAlias(); } + /** + * @param newOwner | New Import provider owner. + * + * @return Clone of this import for newOnwer. + * + * @since 1.3.5 + */ public Import clone(ImportsProvider newOwner) { return new Import(getCls(), getClsAlias(), newOwner); diff --git a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java index 63e9cf9..017d67d 100644 --- a/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java +++ b/SerialX-juss/src/main/java/org/ugp/serialx/juss/converters/ObjectConverter.java @@ -126,6 +126,7 @@ public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Obj } @SuppressWarnings("unchecked") + @Override public Appendable toString(Appendable source, ParserRegistry myHomeRegistry, Object obj, SerializationProtocol preferedProtocol, Object... args) { if (obj instanceof Scope)

    + + +
    + + + +
    +
    +
    +
    +
    +
    +

    Analysis of CodeMR Project

    +

    General Information

    + +
    LOC: -1
    +
    #of classes : -1
    +
    # of packages: -1
    +
    # of external packages: -1
    +
    # of external classes: -1
    +
    # of problematic classes: -1
    +
    # of problematic classes: -1
    + + + + +
    +
    + + + + +
    +
    +
    + +
    +
    +
    +

    Distribution of Quality Attributes

    + + +

    Complexity, Coupling, Cohesion, and Size

    +
    +
    +
    +
    +
    + +
    +
    +
    +

    Metric Values in Sunburst Chart

    +

    Select metric for class, package and the project

    +

    Click to zoom into the packages

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values by Packages

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Metric Values in Treemap Chart

    +

    Select class metric to visualize

    +
    +
    + +
    +
    +
    + +
    +
    +
    +

    Package Dependencies

    +

    Hover on the wheel to see the details

    +
    +
    + +
    +
    +
    + +
    +
    + + + +
    +